È possibile utilizzare un'espressione regolare per far corrispondere qualsiasi stringa eccetto una costante di stringa specifica diciamo "ABC"? È possibile escludere una sola costante di stringa specifica? Grazie del tuo aiuto in anticipo.RegEx per escludere una costante di stringa specifica
risposta
Questo non è facile, a meno che il motore regexp non abbia un supporto speciale per questo. Il modo più semplice sarebbe quella di utilizzare l'opzione negativo-partita, ad esempio:
$var !~ /^foo$/
or die "too much foo";
In caso contrario, si deve fare qualcosa di male:
$var =~ /^(($)|([^f].*)|(f[^o].*)|(fo[^o].*)|(foo.+))$/
or die "too much foo";
che uno dice sostanzialmente "se inizia con non - f
, il resto può essere qualsiasi cosa, se inizia con f
, non o
, il resto può essere qualsiasi cosa, altrimenti, se inizia fo
, il prossimo carattere sarebbe meglio non essere un altro o
".
Ciò non consentirà la stringa vuota, 'f',' fo' e 'foo'. – Gumbo
@ Gumbo: Permette la stringa vuota bene; notare che ($) è la prima alternativa, quindi^$ (stringa vuota) è accettata. L'ho provato, e almeno in perl 5.0.10 la stringa vuota è accettata. – derobert
... mi dispiace, perl 5.10.0, ovviamente! – derobert
È necessario utilizzare un'asserzione lookahead negativa.
(?!^ABC$)
È possibile ad esempio utilizzare quanto segue.
(?!^ABC$)(^.*$)
Se questo non funziona nel tuo editor, prova questo. E 'testato per funzionare in Ruby e JavaScript:
^((?!ABC).)*$
Funzionerà se stai cercando una stringa che non include ABC. Ma è questo l'obiettivo? O è l'obiettivo di abbinare ogni personaggio tranne ABC? –
Grazie per averlo sottolineato, hai ragione - il mio suggerimento evita solo le stringhe che iniziano con ABC - Ho dimenticato di ancorare l'asserzione. Andando a correggere quello. –
Questo è ancora diverso da quello che stavo pensando. Forse l'interrogante chiarirà cosa stanno cercando. –
si potrebbe usare lookahead negativo, o qualcosa di simile:
^([^A]|A([^B]|B([^C]|$)|$)|$).*$
Forse quest'ultimo possa essere semplificato un po'.
In .NET è possibile utilizzare il raggruppamento a vostro vantaggio in questo modo:
http://regexhero.net/tester/?id=65b32601-2326-4ece-912b-6dcefd883f31
noterete che:
(ABC)|(.)
catturerà tutto tranne ABC nel 2 ° gruppo. Le parentesi circondano ciascun gruppo. Così (ABC) è un gruppo e 1 è il gruppo 2.
Quindi basta afferrare il 2 ° gruppo come questo in una sostituzione (.):
$2
O nel look .NET la collezione gruppi all'interno della Classe Regex per un po 'più di controllo.
Si dovrebbe essere in grado di fare qualcosa di simile anche nella maggior parte delle altre implementazioni regex.
UPDATE: ho trovato un modo molto più veloce per fare questo qui: http://regexhero.net/tester/?id=997ce4a2-878c-41f2-9d28-34e0c5080e03
'ancora utilizza il raggruppamento (non riesco a trovare un modo che non fa uso di raggruppamento). Ma questo metodo è oltre 10 volte più veloce del primo.
Prova questa espressione regolare:
^(.{0,2}|([^A]..|A[^B].|AB[^C])|.{4,})$
Esso descrive tre casi:
- meno di tre carattere arbitrario
- esattamente tre caratteri, mentre sia
- il primo non è
A
o - la prima è
A
ma la seconda non èB
, o - il primo è
A
, il secondoB
ma il terzo non èC
- il primo non è
- più di tre caratteri arbitrari
Quale strumento siete voi usando? A seconda dello strumento, potrebbe esserci un modo per specificare questo esterno alla tua espressione regolare. grep supporta l'opzione -v per invertire il senso della corrispondenza, ad esempio. –
Non puoi semplicemente 'se (/^ABC $ /) altro {...} dove il resto sarebbe l'ABC non corrispondente – Xetius
Quindi stai cercando di abbinare ogni carattere di una determinata stringa, eccetto la parte ABC di esso ? In altre parole, "Una stringa con ABC" corrisponderebbe a "Una stringa con". –