web-dev-qa-db-fra.com

c # regex correspond à l'exemple

J'essaie d'obtenir des valeurs en utilisant le texte suivant. Avez-vous des idées à faire avec Regex?

Contribution

Lorem ipsum dolor sit% download% # 456 amet, consectetur adipiscing% download% # 3434 elit. Duis non nunc nec mauris porttitor. Sed Cliquez sur l'image pour l'agrandir% télécharger% # 298. L 'Aeanean dapibus nisl% télécharger% # 893434 id nibh auctor vel tempor velit blandit.

Sortie

456  
3434  
298   
893434 

Merci d'avance.

54
Sha Le

Vous essayez donc de récupérer les valeurs numériques précédées du jeton "% download% #"?

Essayez ce modèle:

(?<=%download%#)\d+

Cela devrait fonctionner. Je ne pense pas que # ou % sont des caractères spéciaux dans .NET Regex, mais vous devrez soit échapper à la barre oblique inversée, comme \\ ou utilisez un chaîne textuelle pour tout le motif:

var regex = new Regex(@"(?<=%download%#)\d+");
return regex.Matches(strInput);

Testé ici: http://rextester.com/BLYCC167

NOTE: L'assertion lookbehind (?<=...) est important car vous ne voulez pas inclure %download%# _ dans vos résultats, seuls les chiffres suivants. Cependant, votre exemple semble en avoir besoin avant chaque chaîne que vous souhaitez capturer. Le groupe lookbehind s'assurera qu'il est présent dans la chaîne d'entrée, mais ne l'inclura pas dans les résultats renvoyés. Plus d'informations sur les affirmations de ressemblance ici.

61
Justin Morgan

Toutes les autres réponses que je vois sont bonnes, mais C # prend en charge les groupes nommés!

J'utiliserais le code suivant:

const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

static void Main(string[] args)
{
    Regex expression = new Regex(@"%download%#(?<Identifier>[0-9]*)");
    var results = expression.Matches(input);
    foreach (Match match in results)
    {
        Console.WriteLine(match.Groups["Identifier"].Value);
    }
}

Le code qui lit: (?<Identifier>[0-9]*) Spécifie que les résultats de [0-9]* Feront partie d'un groupe nommé que nous indexons comme ci-dessus: match.Groups["Identifier"].Value

39
Firoso
    public void match2()
    {
        string input = "%download%#893434";
        Regex Word = new Regex(@"\d+");
        Match m = Word.Match(input);
        Console.WriteLine(m.Value);
    }
5
mohan

Il semble que la plupart des publications décrivent ce dont vous avez besoin ici. Cependant, vous aurez peut-être besoin d'un comportement plus complexe, selon ce que vous analysez. Dans votre cas, il se peut que vous n’ayez pas besoin d’une analyse plus complexe, mais cela dépend des informations que vous extrayez.

Vous pouvez utiliser des groupes de regex comme nom de champ dans la classe, après quoi vous pourriez écrire par exemple comme ceci:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

public class Info
{
    public String Identifier;
    public char nextChar;
};

class testRegex {

    const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. " +
    "Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

    static void Main(string[] args)
    {
        Regex regex = new Regex(@"%download%#(?<Identifier>[0-9]*)(?<nextChar>.)(?<thisCharIsNotNeeded>.)");
        List<Info> infos = new List<Info>();

        foreach (Match match in regex.Matches(input))
        {
            Info info = new Info();
            for( int i = 1; i < regex.GetGroupNames().Length; i++ )
            {
                String groupName = regex.GetGroupNames()[i];

                FieldInfo fi = info.GetType().GetField(regex.GetGroupNames()[i]);

                if( fi != null ) // Field is non-public or does not exists.
                    fi.SetValue( info, Convert.ChangeType( match.Groups[groupName].Value, fi.FieldType));
            }
            infos.Add(info);
        }

        foreach ( var info in infos )
        {
            Console.WriteLine(info.Identifier + " followed by '" + info.nextChar.ToString() + "'");
        }
    }

};

Ce mécanisme utilise la réflexion C # pour définir la valeur sur la classe. Le nom du groupe correspond au nom du champ dans l'instance de la classe. Veuillez noter que Convert.ChangeType n'acceptera aucun type d'ordures.

Si vous souhaitez ajouter un suivi de ligne/colonne - vous pouvez ajouter une division Regex supplémentaire pour les lignes, mais pour conserver la boucle intacte - tous les modèles de correspondance doivent avoir des groupes nommés. (Sinon, l'index de la colonne sera mal calculé)

Cela se traduira par la sortie suivante:

456 followed by ' '
3434 followed by ' '
298 followed by '.'
893434 followed by ' '
2
TarmoPikaro

Ce modèle devrait fonctionner:

#\d

foreach(var match in System.Text.RegularExpressions.RegEx.Matches(input, "#\d"))
{
    Console.WriteLine(match.Value);
}

(Je ne suis pas devant Visual Studio, mais même si cela ne compile pas tel quel, cela devrait être assez proche de Tweak pour obtenir quelque chose qui fonctionne).

0
Adam Robinson
Regex regex = new Regex("%download#(\\d+?)%", RegexOptions.SingleLine);
Matches m = regex.Matches(input);

Je pense que fera l'affaire (non testé).

0
signetro