J'ai la chaîne suivante:

[The quick] brown fox [mykey*="is a super-fast9"] animal [mykey^="that"] can run "very rapid" and [otherkey="effortlessly"].

J'ai besoin d'extraire les mots (séparés par un espace) entre guillemets qui sont en même temps entre crochets qui commencent par un mot-clé spécifique (mykey).

Jusqu'à présent, j'ai:

Le rapide

Mykey * = "est

Une

Ultra-rapide 9 "

Mykey ^ = "que"

Otherkey = "sans effort"

Mais je veux:

Est

Une

Ultra-rapide 9

Cette

Exemple de lien: https://regex101.com/r/zmNse1/2

0
Gabriel Rodriguez 8 août 2017 à 16:15

2 réponses

Meilleure réponse

La solution proposée par Wiktor est la plus logique à utiliser, mais par souci de défi RegEx, consultez ce modèle \[(?!mykey)[^\[]+|([^\s\[=\"]+)(?=[^\"]*\"\]), vérifiez le groupe n ° 1 Démo

\[                  # "["
(?!                 # Negative Look-Ahead
  mykey             # "mykey"
)                   # End of Negative Look-Ahead
[^\[]               # Character not in [\[] Character Class
+                   # (one or more)(greedy)
|                   # OR
(                   # Capturing Group (1)
  [^\s\[=\"]        # Character not in [\s\[=\"] Character Class
  +                 # (one or more)(greedy)
)                   # End of Capturing Group (1)
(?=                 # Look-Ahead
  [^\"]             # Character not in [\"] Character Class
  *                 # (zero or more)(greedy)
  \"                # """
  \]                # "]"
)                   # End of Look-Ahead
2
alpha bravo 8 août 2017 à 14:30

Pour ce que ça vaut: puisque d'autres ont mentionné l'analyse de chaînes, j'ai pensé en donner une implémentation ici. Les options d'analyse de chaîne sont toujours plus longues, mais sont des ordres de grandeur plus rapides que les expressions régulières. En tant que gars qui utilise beaucoup Regex, je peux toujours dire que je préfère les fonctions de chaîne lorsque cela est possible. Les seules complications avec cette réponse sont que vous devez savoir quels sont vos opérateurs d'affectation et que vous ne pouvez pas avoir échappé les guillemets doubles dans votre valeur de chaîne. Je l'ai écrit assez détaillé, bien que vous puissiez supprimer certaines conditions ou raccourcir certaines lignes si vous vouliez moins d'octets de code.

List<string> GetValuesByKeyword(string keyword, string input)
{
    var vals = new List<string>();
    int startIndex = input.IndexOf("[");
    while (startIndex >= 0)
    {
        var newValue = "";
        if (startIndex >= 0 && startIndex < input.Length - 1)
        {
            var squareKey = input.Substring(startIndex + 1).Trim();
            if (squareKey.StartsWith(keyword))
            {
                var squareAssign = squareKey.Substring(keyword.Length).Trim();
                var assignOp = StartsWithWhich(squareAssign, "=", "+=", "-=", "*=", "/=", "^=", "%=");
                if (!string.IsNullOrWhiteSpace(assignOp))
                {
                    var quotedVal = squareAssign.Substring(assignOp.Length).Trim();
                    if (quotedVal.StartsWith("\""))
                    {
                        var endQuoteIndex = quotedVal.IndexOf('"', 1);
                        if (endQuoteIndex > 0)
                        {
                            newValue = quotedVal.Substring(1, endQuoteIndex - 1);
                        }
                    }
                }
            }
        }
        if (!string.IsNullOrWhiteSpace(newValue))
        {
            vals.Add(newValue);
            startIndex = input.IndexOf("[", input.IndexOf(newValue, startIndex) + newValue.Length);
        }
        else startIndex = input.IndexOf("[", startIndex + 1);
    }
    return string.Join(" ", vals).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
0
Suamere 8 août 2017 à 15:20