Regex pour sélectionner tout jusqu'a un certain ensemble de caractères

Avec la chaîne de caractères lorem lorem sinab abc hello, l’expression régulière /^[^abc]*/ sélectionnera lorem lorem sin.

Voir ce regex demo.

Mais je veux que la chaîne correspondante soit lorem lorem sinab ?

Autrement dit, comment puis-je faire sélectionner toutes les chaînes jusqu’à (mais sans inclure) la séquence exacte « abc » ?

Vous n’avez pas précisé quel langage vous utilisez, mais cela fonctionnera presque dans tous les langages les plus populaires.

/.+?(?=abc)/

Voir le demo.

La partie .+? est la version non gourmande de .+ (un ou plusieurs éléments). Lorsque nous utilisons .+, le moteur va en principe tout sélectionné. Ensuite, s’il y a quelque chose d’autre dans la regex, il reviendra en arrière en essayant de faire correspondre la partie suivante. Il s’agit d’un comportement gourmand, c’est-à-dire qu’il s’agit de satisfaire le plus de choses possible.

Lorsque vous utilisez .+?, au lieu de faire correspondre tous les caractères en une seule fois et de revenir en arrière pour d’autres conditions (le cas échéant), le moteur fera correspondre les caractères suivants par étape jusqu’à ce que la partie suivante de la regex soit satisfaite (encore une fois le cas échéant). Il s’agit de la méthode la moins gourmande, c’est-à-dire celle qui consiste à faire correspondre le moins de caractères possible.

Si vous cherchez à capturer tout ce qui va jusqu’à « abc » :

/^(.*?)abc/

Explanation:

( ) capture l’expression à l’intérieur des parenthèses pour l’accès à l’aide de $1, $2, etc.

^ correspond au début de la ligne.

.* correspond à n’importe quoi, ? de manière non obligatoire (correspond au nombre minimum de caractères requis) - La raison pour laquelle cela est nécessaire est que, dans le cas contraire, dans la chaîne suivante :

lorem lorem sinab abc hello abc

Par défaut, les expressions régulières sont gourmandes, ce qui signifie qu’elles correspondent à autant de choses que possible. Ainsi, /^.*abc/ correspondrait à « lorem lorem sinab abc hello ». L’ajout du quantificateur non avide ? fait que la regex ne correspond qu’à « lorem lorem sinab ».

/[\s\S]*?(?=abc)/

Cela sélectionnera:

Dans Python:

.+?(?=abc) fonctionne pour le cas d’une seule ligne.

[^]+?(?=abc) ne fonctionne pas, car python ne reconnaît pas [^] comme une regex valide. Pour que la correspondance multiligne fonctionne, vous devez utiliser l’option re.DOTALL, par exemple :

re.findall('.+?(?=abc)', data, re.DOTALL)