Pour regex, quelle est la syntaxe de recherche jusqu'à mais non incluse? Un peu comme:
Haystack:
The quick red fox jumped over the lazy brown dog
Expression:
.*?quick -> and then everything until it hits the letter "z" but do not include z
La façon explicite de dire "rechercher jusqu'à X
mais sans inclure X
" est la suivante:
(?:(?!X).)*
où X
peut être n'importe quelle expression régulière.
Dans votre cas, cependant, cela pourrait être exagéré - ici le moyen le plus simple serait
[^z]*
Cela correspondra à tout sauf z
et s'arrêtera donc juste avant le prochain z
.
Donc .*?quick[^z]*
Correspondra à The quick fox jumps over the la
.
Cependant, dès que vous avez plusieurs lettres simples à rechercher, (?:(?!X).)*
Entre en jeu, par exemple
(?:(?!lazy).)*
- correspond à tout jusqu'au début du mot lazy
.
Ceci utilise un assertion de lookahead, plus spécifiquement un lookahead négatif.
.*?quick(?:(?!lazy).)*
correspondra à The quick fox jumps over the
.
Explication:
(?: # Match the following but do not capture it:
(?!lazy) # (first assert that it's not possible to match "lazy" here
. # then match any character
)* # end of group, zero or more repetitions.
En outre, lorsque vous recherchez des mots clés, vous pouvez les entourer d'ancres de délimitation Word: \bfox\b
Ne correspondra qu'au mot complet fox
mais pas au renard dans foxy
.
Remarque
Si le texte à mettre en correspondance peut également inclure des sauts de ligne, vous devrez définir l'option "le point correspond à tout" de votre moteur d'expression régulière. Habituellement, vous pouvez y parvenir en ajoutant (?s)
Au regex, mais cela ne fonctionne pas dans tous les moteurs de regex (notamment JavaScript).
Solution alternative:
Dans de nombreux cas, vous pouvez également utiliser une solution plus simple et plus lisible qui utilise un quantificateur paresseux. En ajoutant un ?
Au quantificateur *
, Il essaiera de faire correspondre le moins de caractères possible à partir de la position actuelle:
.*?(?=(?:X)|$)
correspondra à n'importe quel nombre de caractères, s'arrêtant juste avant X
(qui peut être n'importe quelle expression régulière) ou la fin de la chaîne (si X
ne correspond pas). Vous devrez peut-être également définir l'option "le point correspond à tout" pour que cela fonctionne. (Remarque: j'ai ajouté un groupe non capturant autour de X
afin de l'isoler de manière fiable de l'alternance)
Une syntaxe regex anticipée peut vous aider à atteindre votre objectif. Ainsi, une expression régulière pour votre exemple est
.*?quick.*?(?=z)
Et il est important de noter le .*?
correspondance paresseuse avant le (?=z)
lookahead: l'expression correspond à une sous-chaîne jusqu'à ce qu'une première occurrence de la lettre z
.
Voici un exemple de code C #:
const string text = "The quick red fox jumped over the lazy brown dogz";
string lazy = new Regex(".*?quick.*?(?=z)").Match(text).Value;
Console.WriteLine(lazy); // The quick red fox jumped over the la
string greedy = new Regex(".*?quick.*(?=z)").Match(text).Value;
Console.WriteLine(greedy); // The quick red fox jumped over the lazy brown dog
Essaye ça
(.*?quick.*?)z