79 votes

Exemple de correspondances regex en c#

J'essaie d'obtenir des valeurs à partir du texte suivant. Comment faire avec Regex ?

Entrée

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.

Sortie

456  
3434  
298   
893434

83voto

Justin Morgan Points 12853

Vous essayez donc de saisir des valeurs numériques précédées du jeton "%download%#" ?

Essayez ce modèle :

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

Ça devrait marcher. Je ne pense pas que # ou % sont des caractères spéciaux dans .NET Regex, mais vous devrez soit échapper la barre oblique inverse comme suit \\ ou utiliser un chaîne in extenso pour l'ensemble du motif :

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

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

NOTA: L'assertion "lookbehind (?<=...) est important car vous ne voulez pas inclure %download%# dans vos résultats, seulement les chiffres qui le suivent. Cependant, votre exemple semble l'exiger avant chaque chaîne que vous voulez 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. Pour en savoir plus sur les assertions de type "lookaround", cliquez ici.

48voto

Firoso Points 2852

Toutes les autres réponses que je vois sont correctes, mais le 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 se lit : (?<Identifier>[0-9]*) précise que [0-9]* Les résultats de ce dernier feront partie d'un groupe nommé que nous indexons comme ci-dessus : match.Groups["Identifier"].Value

1 votes

Pas besoin de les nommer, utilisez simplement @"%download%#( \d *)" et vous aurez le résultat dans match.Groups[1].Value

8voto

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

0 votes

Un bon et simple exemple, ajouté dans notre post Exemples de regex en C# Merci

4voto

TarmoPikaro Points 11

Il semble que la plupart des messages ici décrivent ce dont vous avez besoin. Cependant, vous pourriez avoir besoin d'un comportement plus complexe, en fonction de ce que vous analysez. Dans votre cas, il se peut que vous n'ayez pas besoin d'une analyse syntaxique plus complexe, mais cela dépend des informations que vous extrayez.

Vous pouvez utiliser des groupes regex comme nom de champ dans la classe, après quoi on pourrait é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 de la classe. Le nom du groupe est comparé au nom du champ dans l'instance de la classe. Veuillez noter que Convert.ChangeType n'accepte aucun type de déchets.

Si vous voulez ajouter le suivi de la ligne / colonne - vous pouvez ajouter une division Regex supplémentaire pour les lignes, mais afin de garder la boucle for intacte - tous les modèles de correspondance doivent avoir des groupes nommés. (Sinon, l'index de la colonne sera calculé de manière incorrecte).

Le résultat sera le suivant :

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

1voto

signetro Points 438
Regex regex = new Regex("%download#(\\d+?)%", RegexOptions.SingleLine);
Matches m = regex.Matches(input);

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X