Comment faire correspondre «quelque chose jusqu’à cette séquence de caractères» dans une expression régulière?

Prenez cette expression régulière: /^[^abc]/ . Cela correspondra à n’importe quel caractère au début d’une chaîne, sauf a, b ou c.

Si vous ajoutez un * après lui – /^[^abc]*/ – l’expression régulière continuera à append chaque caractère suivant au résultat, jusqu’à ce qu’il rencontre un a , ou b , ou c .

Par exemple, avec la chaîne source "qwerty qwerty whatever abc hello" , l’expression correspondra à "qwerty qwerty wh" .

Mais que faire si je voulais que la chaîne correspondante soit "qwerty qwerty whatever "

… En d’autres termes, comment puis-je tout faire correspondre à (mais sans inclure) la séquence exacte "abc" ?

Vous n’avez pas spécifié la saveur de regex que vous utilisez, mais cela fonctionnera dans toutes les versions les plus populaires pouvant être considérées comme “complètes”.

 /.+?(?=abc)/ 

Comment ça marche

Le .+? partie est la version non gourmande de .+ (un ou plusieurs de tous). Lorsque nous utilisons .+ , Le moteur correspondra essentiellement à tout. Ensuite, s’il y a quelque chose d’autre dans le regex, il reviendra par étapes en essayant de faire correspondre la partie suivante. C’est le comportement gourmand , signifiant autant que possible satisfaire .

En utilisant .+? , au lieu de faire correspondre tout à la fois et de revenir à d’autres conditions (le cas échéant), le moteur fera correspondre les caractères suivants par étape jusqu’à ce que la partie suivante de l’expression régulière soit mise en correspondance (le cas échéant). C’est le non-gourmand , c’est -à- dire le plus petit nombre possible de satisfaire .

 /.+X/ ~ "abcXabcXabcX" /.+/ ~ "abcXabcXabcX" ^^^^^^^^^^^^ ^^^^^^^^^^^^ /.+?X/ ~ "abcXabcXabcX" /.+?/ ~ "abcXabcXabcX" ^^^^ ^ 

Après cela, nous avons (?= {contents} ) , une assertion de largeur zéro , un regard autour de nous . Cette construction groupée correspond à son contenu, mais ne compte pas comme des caractères correspondants ( largeur zéro ). Il ne retourne que s’il s’agit d’une correspondance ou non ( assertion ).

En d’autres termes, le regex /.+?(?=abc)/ signifie:

Faites correspondre tous les caractères aussi peu que possible jusqu’à ce qu’un “abc” soit trouvé, sans compter le “abc”.

Si vous cherchez à tout capturer jusqu’à “abc”:

 /^(.*?)abc/ 

Explication:

( ) capturer l’expression entre parenthèses pour un access en utilisant $1 , $2 , etc.

^ match début de ligne

.* correspondre à rien ? non goulûment (correspond au nombre minimum de caractères requirejs) – [1]

[1] La raison pour laquelle cela est nécessaire est que sinon, dans la chaîne suivante:

 whatever whatever something abc something abc 

par défaut, les expressions rationnelles sont gourmandes , ce qui signifie qu’elles correspondent autant que possible. Par conséquent, /^.*abc/ correspondrait à “quelque chose d’abc quelque chose”. Ajouter le quantificateur non gourmand ? fait que les regex ne correspondent qu’à “quelque chose”.

Comme @Jared Ng et @Issun l’ont fait remarquer, la clé pour résoudre ce genre de RegEx comme “tout faire correspondre à un certain mot ou à une sous-chaîne” ou “tout correspondre après un certain mot ou une sous-chaîne” s’appelle . En savoir plus sur eux ici.

Dans votre cas particulier, cela peut être résolu par une vision positive. Une image vaut mieux que mille mots. Voir l’explication détaillée dans la capture d’écran.

Capture d'écran Regex101

Qu’est-ce que vous avez besoin est regarder autour de l’assertion comme .+? (?=abc) .+? (?=abc) .

Voir: Lookahead et Lookbehind Zero-Length Assertions

Sachez que [abc] n’est pas la même chose que abc . Entre parenthèses, ce n’est pas une chaîne – chaque caractère n’est qu’une des possibilités. En dehors des supports, il devient la chaîne.

Cela aura du sens à propos des regex.

  1. Le mot exact peut être obtenu à partir de la commande regex suivante:

(“(.*?)”)/g

Ici, nous pouvons obtenir le mot exact globalement qui appartient aux guillemets. Par exemple, si notre texte de recherche est,

Ceci est l’exemple des mots “à guillemets”

alors nous aurons “double guillemets” de cette phrase.

Pour regex en Java, et je crois aussi dans la plupart des moteurs de regex, si vous souhaitez inclure la dernière partie, cela fonctionnera:

 .+?(abc) 

Par exemple, dans cette ligne:

 I have this very nice senabctence 

sélectionner tous les caractères jusqu’à “abc” et inclure également abc

en utilisant notre regex, le résultat sera: I have this very nice senabc

Testez ceci: https://regex101.com/r/mX51ru/1

Je crois que vous avez besoin de sous-expressions. Si je me souviens bien, vous pouvez utiliser les parenthèses normales () pour les sous-expressions.

Cette partie est de grep manuel:

  Back References and Subexpressions The back-reference \n, where n is a single digit, matches the subssortingng previously matched by the nth parenthesized subexpression of the regular expression. 

Faire quelque chose comme ^[^(abc)] devrait faire l’affaire.

Le $ marque la fin d’une chaîne, donc quelque chose comme ça devrait fonctionner: [[^abc]*]$ où vous recherchez tout ce qui ne se termine PAS dans une itération de abc , mais cela devrait être à la fin

De plus, si vous utilisez un langage de script avec regex (comme php ou js), ils ont une fonction de recherche qui s’arrête quand ils rencontrent un pattern (et vous pouvez spécifier start à partir de la gauche ou de php, vous pouvez faire une implode pour refléter la chaîne).

essaye ça

 .+?efg 

Requête:

 select REGEXP_REPLACE ('abcdefghijklmn','.+?efg', '') FROM dual; 

sortie:

 hijklmn