Regex: abbina tutto tranne uno schema specifico


310

Ho bisogno di un regex in grado di abbinare tutto tranne una stringa che inizia con uno schema specifico (in particolare index.phpe ciò che segue, come index.php?id=2342343)


E quale modello specifico non vuoi abbinare?
Dominic Rodger,

2
C'è un motivo per cui non puoi abbinarti al tuo schema e non fare qualcosa se la stringa corrisponde?
Thomas Owens,


@ThomasOwens: dipende. Dipende da quale parte dell'espressione deve essere negata. Se l'intera espressione deve essere negata, allora hai un punto. Ad esempio, se si desidera codificare "se la stringa non contiene" Bruce "come sottostringa, quindi fare qualcosa", si userebbe chiaramente / Bruce / e si inserirà la negazione nell'istruzione if, al di fuori del regex . Ma potrebbe essere che ti piacerebbe negare qualche sottoespressione. Diciamo, stai cercando qualcosa come il cognome cognome, dove il nome è Bruce, e il cognome è tutto tranne XYZ, dove XYZ è il cognome di una celebrità chiamata Bruce.
matematica compresa il

Risposte:


250

Non sono un esperto di regexp, ma penso che potresti usare un lookahead negativo dall'inizio, ad es. ^(?!foo).*$Non dovresti abbinare nulla con cui iniziare foo.


7
Con grep usa -P per abilitare lookahead.
Seppo Enarvi,

Se non corrisponde "foo" o "bar" è il vostro comportamento desiderato, controllare questa risposta: stackoverflow.com/a/2404330/874824
dave_k_smith

15
Questa risposta è sbagliata, un rapido test lo dimostra. Credo che ciò che si intende è ^((?!foo).)*$( stackoverflow.com/a/406408/3964381 )
Gilad Mayani

4
Per favore, potresti spiegare i simboli che hai usato e perché li hai usati?
Rotimi-best

339

Regex: abbina tutto ma :

Nota dimostrativa : la nuova riga \nviene utilizzata all'interno delle classi di caratteri negati nelle demo per evitare l'overflow della corrispondenza con le linee vicine. Non sono necessari durante il test di singole stringhe.

Nota di ancoraggio : in molte lingue, utilizzare \Aper definire l'inizio non ambiguo della stringa e \z(in Python, è \Z, in JavaScript, $è OK) per definire la fine della stringa.

Nota a punti : in molti gusti (ma non POSIX, TRE, TCL), .corrisponde a qualsiasi carattere ma a un carattere newline . Assicurati di usare un modificatore DOTALL corrispondente ( /sin PCRE / Boost / .NET / Python / Java e /min Ruby) per .far corrispondere qualsiasi carattere incluso un newline.

Nota sulla barra rovesciata : nelle lingue in cui è necessario dichiarare modelli con stringhe C che consentono sequenze di escape (come \nper una nuova riga), è necessario raddoppiare le barre rovesciate sfuggendo a caratteri speciali in modo che il motore possa trattarli come caratteri letterali (ad esempio in Java, world\.sarà dichiarato come "world\\."o utilizzare una classe di caratteri:) "world[.]". Usa valori letterali di stringa grezzi (Python r'\bworld\b'), valori letterali di stringa verbali C # @"world\."o stringhe slashy / notazioni letterali regex come /world\./.


Ottimo scrivere! Nel caso di "una stringa (non) uguale a una stringa", con l'esempio di ^(?!foo$), perché il simbolo del dollaro deve essere tra parentesi affinché l'espressione funzioni? Mi aspettavo ^(?!foo)$di dare gli stessi risultati, ma non lo è.
Concedi Humphries il

3
@GrantHumphries: quando l' $ancora si trova all'interno del lookahead, fa parte della condizione, parte di quell'asserzione di larghezza zero . Se fosse esterno, come in ^(?!foo)$, farà parte del modello di consumo che richiede la fine della stringa subito dopo l'inizio della stringa, rendendo il lookahead negativo irrilevante poiché restituirebbe sempre true (non può esserci testo dopo la fine della stringa , figuriamoci foo). Pertanto, l' ^(?!foo$)inizio delle corrispondenze di una stringa non seguita da fooquella seguita dalla fine della stringa. ^(?!foo)$corrisponde a una stringa vuota.
Wiktor Stribiżew,

@ robots.txt Rimuovi questi commenti. Stai facendo una domanda XY. Le classi di caratteri devono corrispondere a singoli caratteri, non è possibile definire una sequenza di caratteri con essi. Probabilmente dovresti semplicemente trovare la sottostringa tra l'inizio di una stringa e la prima occorrenza di coto lan, e rimuovere la corrispondenza, come regex.replace(myString, "^.*?(?:cot|lan)\s*", "").
Wiktor Stribiżew,

Caro Wiktor. Hai chiuso la mia domanda ma la tua risposta collegata non riesce. Ho aggiornato la mia domanda stackoverflow.com/questions/60004380/…
MonsterMMORPG

Ad esempio la tua risposta collegata non riesce in questo esempio "ing pacchetti <! - e la pagina web <! - asdasasdas -> gli editor ora usano -> Lorem Ipsum"
MonsterMMORPG

259

Puoi inserire ^a all'inizio di un set di caratteri per abbinare qualsiasi cosa tranne quei personaggi.

[^=]*

corrisponderà a tutto ma =


55
È vero, ma elabora solo un personaggio alla volta. Se vuoi escludere una sequenza di due o più caratteri, devi usare un lookahead negativo come hanno detto gli altri responder.
Alan Moore,

soluzione perfetta per rimuovere qualsiasi carattere indesiderato tranne quelli nel modello. grazie
Sirmyself

@Alan, "... devi usare uno sguardo negativo ..." non è corretto, ma non dovremmo essere troppo duri con te perché Wiktor non ha pubblicato la sua risposta - il che mostra perché - fino al 2016.
Cary Swoveland

6

Basta abbinare /^index\.php/quindi respingere qualsiasi cosa corrisponda.


Forse scritto str !~ /\Aindex\.php/.
Cary Swoveland,

6

In pitone:

>>> import re
>>> p='^(?!index\.php\?[0-9]+).*$'
>>> s1='index.php?12345'
>>> re.match(p,s1)
>>> s2='index.html?12345'
>>> re.match(p,s2)
<_sre.SRE_Match object at 0xb7d65fa8>

3
Ciò rifiuterà "index_php" o "index # php".

1

Ho bisogno di un regex in grado di abbinare tutto ma tranne una stringa che inizia con index.php uno schema specifico (in particolare index.php e ciò che segue, come index.php? Id = 2342343)

Usa il metodo Exec

    let match,
        arr = [],
        myRe = /([\s\S]+?)(?:index\.php\?id.+)/g;

    var str = 'http://regular-viragenia/index.php?id=2342343';

    while ((match = myRe.exec(str)) != null) {
         arr.push(match[1]);
    } 
    
    console.log(arr);

var myRe = /([\s\S]+?)(?:index\.php\?id=.+)/g;
var str = 'http://regular-viragenia/index.php?id=2342343';
var matches_array = myRe.exec(str);
console.log(matches_array[1]);

O ALTRE PARTITE

let match,
            arr = [],
            myRe = /index.php\?id=((?:(?!index)[\s\S])*)/g;

        var str = 'http://regular-viragenia/index.php?id=2342343index.php?id=111index.php?id=222';

        while ((match = myRe.exec(str)) != null) {
             arr.push(match[1]);
        } 

        console.log(arr);


-13

Che ne dici di non usare regex:

// In PHP
0 !== strpos($string, 'index.php')

11
L'OP ha richiesto specificamente una regex ... Non sono sicuro che questo aiuti! (Potrebbe utilizzare grepla riga di comando, ad esempio, o Perl / Python / qualsiasi altra lingua o un comando "Esegui questa regex per ogni riga" in un editor di testo, ecc ...)
rinogo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.