2009-03-04 14 views

risposta

182

Si potrebbe utilizzare un'asserzione look-ahead:

(?!999)\d{3} 

Questo esempio corrisponde a tre cifre diverse da 999.


Ma se vi capita di non avere un'implementazione espressione regolare con questa funzione (vedere Comparison of Regular Expression Flavors), probabilmente necessario costruire un'espressione regolare con le caratteristiche di base per conto proprio.

Un'espressione regolare compatibile con sintassi di base solo sarebbe:

[0-8]\d\d|\d[0-8]\d|\d\d[0-8] 

questo non corrisponde con nessun anche tre sequenza di cifre che non è 999.

+1

Look-ahead non è una sintassi di espressione regolare standard, è un'estensione Perl, funzionerà solo in Perl, PCRE (RegEx compatibile con Perl) o altre implementazioni non standard – Juliano

+9

Potrebbe non essere standard, ma non la maggior parte delle lingue moderne lo supporta? In che lingua * non * viene supportato lo sguardo avanti di questi tempi? –

+0

È vero. Ma la maggior parte degli aromi regex supporta questa funzione (vedi ). – Gumbo

15

Combinare lo schema e utilizzare la lingua host per invertire il risultato booleano della partita. Questo sarà molto più leggibile e mantenibile.

+1

Quindi mi ritrovo con (~ A o B) anziché (A e ~ B) Non risolve il mio problema – notnot

+1

Pseudo-codice: String toTest; if (toTest.matches (A) AND! ToTest.matches (B)) {...} –

+0

Avrei dovuto essere più chiaro - i pezzi non sono completamente indipendenti: se A corrisponde a una parte della stringa, ci interessa se ~ B corrisponde al resto di esso (ma non necessariamente tutto). Questo era per la funzione findstr della riga di comando di Windows, che ho trovato è limitato a regex reali, quindi punto controverso. – notnot

4

Il complemento di una lingua normale è anche un linguaggio normale, ma per costruirlo è necessario creare il DFA per la lingua normale e apportare eventuali modifiche di stato valide in un errore. Vedere this per un esempio. Quello che la pagina non dice è che ha convertito /(ac|bd)/ in /(a[^c]?|b[^d]?|[^ab])/. La conversione da un DFA a un'espressione regolare non è banale. È più facile se puoi usare l'espressione regolare immutata e cambiare la semantica nel codice, come suggerito in precedenza.

+2

Se avessi a che fare con le regex effettive, tutto ciò sarebbe discutibile. Regex ora sembra riferirsi al nebuloso spazio CSG-ish (?) Del pattern matching che supporta la maggior parte delle lingue. Dato che ho bisogno di corrispondere (A e ~ B), non c'è modo di rimuovere la negazione e continuare a fare tutto in un solo passaggio. – notnot

+0

Lookahead, come descritto sopra, lo avrebbe fatto se findstr avesse fatto qualcosa oltre le regex di DFA. Il tutto è un po 'strano e non so perché devo fare questo stile da riga di comando (batch ora). È solo un altro esempio delle mie mani legate. – notnot

+1

@notnot: stai usando findstr da Windows? Allora hai solo bisogno di/v. Come: findstr Un file di input | findstr/v B> outputfile.txt Il primo corrisponde a tutte le linee con A, il secondo corrisponde a tutte le linee che non hanno B. – Juliano

1

modello - re

str.split(/re/g) 

tornerà tutto tranne il modello.

prova here

+0

Probabilmente vorrai dire che devi unirti di nuovo. – tomdemuyt

+0

Un approccio simile sta usando 'replace' ' str.replace (/ re/g, '') ', quindi non è necessario ricongiungerli. anche se si butta in un file \ s? come 'str.replace (/ \ re \ s?/g, '')' poi ti sbarazzi degli spazi duplicati che avresti da qualcosa che viene sostituito nel mezzo di una stringa – jakecraige

0
(B)|(A) 

quindi utilizzare quale gruppo 2 cattura ...

+0

Ha bisogno di * catturare * non B, il suo scopo non è quello di ignorare tutti i modelli B. – hexicle

+0

Forse è sbagliato, ma era esattamente quello che stavo cercando – user3473534

25

Se si desidera far corrispondere una parola A in una stringa e di non abbinare una parola B. Per esempio: Se hai un testo:

1. I have a two pets - dog and a cat 
2. I have a pet - dog 

Se si desidera effettuare la ricerca per le linee di testo che avere un cane per un animale domestico e NON HA gatto è possibile utilizzare questa espressione regolare:

^(?=.*?\bdog\b)((?!cat).)*$ 

troverà solo la seconda linea:

2. I have a pet - dog 
+0

Non l'ha menzionato nella domanda, ma l'OP sta effettivamente usando il comando DOS 'findstr'. Offre solo un piccolo sottoinsieme delle funzionalità che ci si aspetta di trovare in uno strumento regex; lookahead non è tra questi. (Ho appena aggiunto il tag [tag: findstr].) –

+2

hm, sì, l'ho trovato in uno dei suoi commenti sui post. Ho visto Regex nel titolo. Ad ogni modo, se qualcuno trova questo post quando cerca lo stesso per l'espressione regolare, come ho fatto io, forse potrebbe essere utile a qualcuno :) grazie per i commenti – Aleks

+1

Grazie Aleks. Proprio come hai immaginato, mi sono imbattuto in questa domanda a causa del titolo e hai risposto molto bene per me. – Hagelt18

7

notnot, resuscitare questa antica domanda perché aveva una soluzione semplice che wasn' ho menzionato (Trova la tua domanda mentre fai qualche ricerca per un regex bounty quest.)

Sono di fronte a una situazione in cui devo corrispondere a uno schema (A e ~ B) .

l'espressione regolare di base per questo è spaventosamente semplice: B|(A)

Basta ignorare le partite complessive e di esaminare le catture del gruppo 1, che conterrà A.

Un esempio (con tutte le rinunce su parsing html regex): a è cifre, B è all'interno cifre <a tag

La regex: <a.*?<\/a>|(\d+)

Demo (vedi gruppo 1 nel riquadro in basso a destra)

Riferimento

How to match pattern except in situations s1, s2, s3

How to match a pattern unless...

0

La mia risposta qui potrebbe risolvere il problema così:

https://stackoverflow.com/a/27967674/543814

  • Invece di Sostituisci, si utilizzerà Match.
  • Invece del gruppo $1, leggere il gruppo $2.
  • Il gruppo $2 è stato reso non-catturante lì, che si eviterebbe.

Esempio:

Regex.Match("50% of 50% is 25%", "(\d+\%)|(.+?)");

Il primo gruppo di cattura specifica il modello che si vuole evitare. L'ultimo gruppo catturante cattura tutto il resto. Basta leggere quel gruppo, $2.

Problemi correlati