8
votes

Comment extraire les chaînes entre deux caractères spéciaux en utilisant des expressions régulières en C #

Je suis totalement nouveau à des expressions régulières. Et ce que j'ai besoin pour atteindre, c'est que j'ai une variable de chaîne contenant la chaîne suivante par exemple,

"mon nom est # p_name # et je suis # p_age # ans" p>

J'ai besoin d'extraire Les deux chaînes P_NAME et P_AGE à l'aide d'expressions régulières (à une matrice de chaîne ou à deux variables de chaîne, etc.). c'est-à-dire que la chaîne commence par un # et se termine par un # et j'ai besoin d'extraire la partie centrale. p>

Comment puis-je faire cela en C # en utilisant des expressions régulières. P>

et comment Puis-je extraire le même ci-dessus au cas où j'ai un nouveau caractère de ligne entre aussi. C'est-à-dire par exemple, p>

"mon nom est # p_name # et \ r \ n je suis # p_age # ans". P>

Merci P>

Merci tout le monde. .. P>

Après avoir travaillé pour moi ... Je ne peux pas publier ma propre réponse comme réponse jusqu'à 8 heures à expiration de Stackoverflow ... :) p>

string str = "My Name is #P_NAME# and \r\n I am #P_AGE# years old";

MatchCollection allMatchResults = null;
var regexObj = new Regex(@"#\w*#");
allMatchResults = regexObj.Matches(str);


0 commentaires

7 Réponses :


-2
votes

Essayez d'utiliser

var format = "My Name is #P_NAME# and \r\n I am #P_AGE# years old";
Regex rgxp = new Regex(@"#[(?<name>\S+)\]#", RegexOptions.Compiled);
Match m = rgxp .Match(format);
if (true == m.Success)
{
   return m.Groups["name"].Value;     // <-- this statement returns the value you're looking for
}


7 commentaires

-1. Cette réponse a beaucoup de problèmes. Pour commencer, le code ne compilera même pas, et s'il l'a fait, la regex ne compilerait pas.


-1 convenu - quelle est la regex ici? Ou destiné à faire?


@el: J'ai remarqué ma typo - j'ai manqué la définition du format var


@alan: J'ai remarqué mon typo - j'ai manqué la définition du format var


C'est un début, mais la déclaration à l'intérieur du bloc si est toujours juste une référence - ce n'est pas faire n'importe quoi. Et la regex ne compilera pas car il a une touche non évaluée Ouverture Square Support suivie d'un support de fermeture Square Square, quand il n'a pas besoin de crochets du tout; @ "# (? \ s +) #" va bien. J'ai appris d'expérience pour tester tout le code avant de la publier ici; Un typo trivial peut le rendre, pas seulement incorrect, mais incompréhensible. Et avec des sites tels que ideone.com disponible, il n'y a pas d'excuse pas à tester.


@Alan: Je prends votre commentaire comme un retour précieux. Êtes-vous lié au fait que ma réputation a diminué de 500 points en une seule journée? À la date de référence - je voulais donner à l'utilisateur la syntaxe pour obtenir la valeur réelle sans savoir ce qu'il / elle veut faire avec elle. J'aurais pu simplement ajouter une déclaration à l'impression à la console, mais pensée non nécessaire


Si vous avez vraiment perdu 500 représentants en une journée, vous devez le supporter avec les administrateurs. Ce n'est certainement pas le résultat de quoi que ce soit i a fait.



2
votes

ESSAYE -

var results = new List<string>();
var subjectString = "My Name is #P_NAME# and \r\n I am #P_AGE# years old";
Regex regexObj = new Regex("#.+?#");
Match matchResults = regexObj.Match(subjectString);
while (matchResults.Success) {
    results.Add(matchResults.ToString().Replace("#",""));
    matchResults = matchResults.NextMatch();
}


1 commentaires

Pourquoi Ignorecase et Multiline sont-ils spécifiés? MULTILINE n'affecte que les caractères ^ et $, et il n'y a pas de caractères littéraux spécifiés do Ignorecase ne fait rien.



10
votes

Une expression régulière telle que "# [^ #] + #" correspondrait à un hachage, suivi d'un ou de plusieurs caractères sans hachage, suivi d'un autre hachage.

Il existe différentes alternatives qui fonctionneraient pour cela, tels que "#. *? #" .

Le code suivant irait le # P_NAME # et # P_AGE #. xxx


1 commentaires

L'option singline ne serait nécessaire que si les espaces réservés pouvaient contenir des lignes ligne (par exemple, #p \ nname # ), ce qui ne semble pas très probable.



30
votes

Vous pouvez le faire comme ceci xxx

démo ici

i Je ne sais pas quelle est votre candidature, mais je dois dire que ce n'est pas une méthode de transfert de données très robuste. Commencez à obtenir quelques autres # s intérieur et tout va mal. Par exemple, des personnes avec # dans leurs noms!

Cependant, si vous pouvez vous garantir que vous travaillerez toujours avec une chaîne de ce format, cela fonctionne. < p> Explication de la regex # (. +?) #

premier # correspond à un # < p> ( commence un groupe . indexé dans .groups [1] dans le code. [0] est l'ensemble correspondant par exemple #dave # non seulement Dave

. +? correspond au moins un caractère. . est un caractère. + est la répétition (au moins une fois que). Et ? indique au moteur de regex d'être paresseux - alors ne correspond pas à un # comme cela sera assorti par notre final #

) ferme le groupe

# correspond à un autre # - la "fermeture" dans ce cas < / p>


0 commentaires

2
votes

Merci tout le monde ...

Après avoir travaillé pour moi ... xxx

"AllMatchResults" contient # p_name # et # p_age # (c'est-à-dire y compris # caractère). Mais avoir aide mon autre logique


1 commentaires

Avez-vous été aidé à trouver cette réponse par d'autres affiches, à savoir Samjudson, IPR101 ou moi-même?



3
votes

Voici une méthode d'extension basée sur cette ... Profitez-en. :)

BTW - cela ne garde pas les caractères # - quelque chose que je ne voulais pas - vous pouvez changer la regex à ceux ci-dessus pour obtenir cela. p>

public static class StringExtensions
{
    ///----------------------------------------------------------------------
    /// <summary>
    /// Gets the matches between delimiters.
    /// </summary>
    /// <param name="source">The source string.</param>
    /// <param name="beginDelim">The beginning string delimiter.</param>
    /// <param name="endDelim">The end string delimiter.</param>
    /// <returns></returns>
    /// <example>
    /// string beginDelim = "<span>";
    /// string endDelim = "</span>";
    /// string input = string.Format("My Name is {0}Lance{1} and I am {0}39{1} years old", beginDelim, endDelim);
    ///
    /// var values = input.GetMatches(beginDelim, endDelim);
    /// foreach (string value in values)
    /// {
    ///     Console.WriteLine(value);
    /// }
    /// </example>
    ///----------------------------------------------------------------------
    public static IEnumerable<string> GetMatches(this string source, string beginDelim, string endDelim)
    {
        Regex reg = new Regex(string.Format("(?<={0})(.+?)(?={1})", Regex.Escape(beginDelim), Regex.Escape(endDelim)));
        MatchCollection matches = reg.Matches(source);
        return (from Match m in matches select m.Value).ToList();
    }
}


1 commentaires

Étant donné que des caractères spéciaux nécessitent souvent une échappée pour être traité comme des motifs littéraux, j'ai ajouté regex.escape pour Begindelim et enddelim .



0
votes

Personne non mentionné des cas multilignes, donc si vous avez une chaîne multiligne, comme: xxx

Vous devez spécifier le drapeau singleline pour ignorer la nouvelle ligne caractères et échapper à la barre oblique.

réponse posté pour les futurs lecteurs


0 commentaires