Come abbinare “qualsiasi cosa fino a questa sequenza di caratteri” in un’espressione regolare?

Prendi questa espressione regolare: /^[^abc]/ . Questo corrisponderà a qualsiasi singolo carattere all’inizio di una stringa, tranne a, b, o c.

Se aggiungi un * dopo – /^[^abc]*/ – l’espressione regolare continuerà ad aggiungere ogni carattere successivo al risultato, finché non incontra un a , o b , o c .

Ad esempio, con la stringa di origine "qwerty qwerty whatever abc hello" , l’espressione corrisponderà a "qwerty qwerty wh" .

Ma cosa succede se volevo che la stringa corrispondente fosse "qwerty qwerty whatever "

… In altre parole, come posso abbinare tutto fino a (ma non includendo) la sequenza esatta "abc" ?

Non hai specificato quale sapore della regex stai usando, ma funzionerà in uno dei più popolari che può essere considerato “completo”.

 /.+?(?=abc)/ 

Come funziona

Il .+? parte è la versione non-golosa di .+ (uno o più di qualsiasi cosa). Quando usiamo .+ , Il motore fondamentalmente corrisponde a tutto. Quindi, se c’è qualcos’altro nella regex, tornerà indietro nei passaggi cercando di far corrispondere la parte seguente. Questo è il comportamento avido , che significa il più ansible da soddisfare .

Quando si utilizza .+? , invece di fare il match tutto in una volta e tornare indietro per le altre condizioni (se ce ne sono), il motore corrisponderà ai caratteri successivi per step fino a che la parte successiva della regex non viene eguagliata (se ansible). Questo è il non-avido , che significa abbinare il minor numero ansible di soddisfare .

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

Di seguito abbiamo (?= {contents} ) , un’asserzione di larghezza zero , un’occhiata in giro . Questa costruzione raggruppata corrisponde al suo contenuto, ma non conta come caratteri corrispondenti ( larghezza zero ). Ritorna solo se è una corrispondenza o meno ( asserzione ).

Quindi, in altri termini la regex /.+?(?=abc)/ significa:

Abbina tutti i personaggi il meno ansible finché non viene trovato un “abc”, senza contare “abc”.

Se stai cercando di catturare tutto fino a “abc”:

 /^(.*?)abc/ 

Spiegazione:

( ) cattura l’espressione tra parentesi per l’accesso usando $1 , $2 , ecc.

^ corrisponde all’inizio della linea

.* corrisponde a qualcosa ? non avido (corrisponde al numero minimo di caratteri richiesto) – [1]

[1] Il motivo per cui questo è necessario è che altrimenti, nella seguente stringa:

 whatever whatever something abc something abc 

per impostazione predefinita, le espressioni regolari sono golose , nel senso che corrisponderanno il più ansible. Pertanto /^.*abc/ corrisponderebbe a “qualunque cosa qualcosa di abc qualcosa”. Aggiungere il quantificatore non avido ? rende la regex corrispondente solo “qualunque sia qualcosa”.

Come hanno sottolineato @Jared Ng e @Issun, la chiave per risolvere questo tipo di RegEx come “abbinare tutto a una determinata parola o sottostringa” o “abbinare tutto dopo una determinata parola o sottostringa” è chiamata “lookaround” asserzioni a lunghezza zero . Leggi di più su di loro qui.

Nel tuo caso particolare, può essere risolto da uno sguardo positivo avanti. Un’immagine vale più di mille parole. Vedi la spiegazione dettagliata nello screenshot.

Screenshot Regex101

Quello di cui hai bisogno è guardare intorno all’asserzione come .+? (?=abc) .+? (?=abc) .

Vedi: Lookahead e Lookbehind Zero-Length Assertions

Si noti che [abc] non è la stessa di abc . All’interno di parentesi non è una stringa – ogni personaggio è solo una delle possibilità. Fuori dalle parentesi diventa la stringa.

Questo ha senso riguardo regex.

  1. La parola esatta può essere ottenuta dal seguente comando regex:

( “(. *?)”) / G

Qui, possiamo ottenere globalmente la parola esatta che appartiene alle doppie virgolette. Ad esempio, se il nostro testo di ricerca è,

Questo è l’esempio per le parole “double quoted”

allora otterremo “doppia citazione” da quella frase.

Per regex in Java, e credo anche nella maggior parte dei motori regex, se vuoi includere l’ultima parte questo funzionerà:

 .+?(abc) 

Ad esempio, in questa riga:

 I have this very nice senabctence 

seleziona tutti i caratteri fino a “abc” e includi anche abc

usando il nostro regex, il risultato sarà: I have this very nice senabc

Prova questo: https://regex101.com/r/mX51ru/1

Credo che tu abbia bisogno di sottoespressioni. Se ricordo bene, puoi usare le parentesi normali () per sottoespressioni.

Questa parte è dal manuale di grep:

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

Fai qualcosa come ^[^(abc)] dovrebbe fare il trucco.

Il $ segna la fine di una stringa, quindi qualcosa del genere dovrebbe funzionare: [[^abc]*]$ dove stai cercando qualcosa che NON FINISCE in qualsiasi iterazione di abc , ma dovrebbe essere alla fine

Inoltre, se stai usando un linguaggio di scripting con espressioni regolari (come php o js), hanno una funzione di ricerca che si ferma quando incontra per la prima volta un pattern (e puoi specificare iniziare da sinistra o iniziare da destra, o con php, puoi fare un implode per rispecchiare la stringa).

prova questo

 .+?efg 

Domanda:

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

produzione :

 hijklmn