Schema Regex - Consenti alfanumerici, un gruppo di caratteri speciali, ma non una determinata sequenza di caratteri
-
06-07-2019 - |
Domanda
Ho la seguente regex:
(?!^[&#]*$)^([A-Za-z0-9-'.,&@:?!()$#/\\]*)$
Consenti quindi A-Z, a-Z, 0-9 e questi caratteri speciali '.,&@:?!()$#/\
Voglio NON corrispondere se il seguente set di caratteri si trova in qualsiasi punto della stringa in questo ordine:
&#
Quando eseguo questo regex con solo " & amp; # " come input, non corrisponde al mio modello, ottengo un errore, ottimo. Quando eseguo il regex con '., & Amp; @:?! () $ # / \ ABC123
corrisponde al mio modello, nessun errore.
Tuttavia quando lo eseguo con:
'.,&#@:?!()$#/\ABC123
Neanche si sbaglia. Sto facendo qualcosa di sbagliato con il controllo per la sequenza & amp; #.
Qualcuno può dirmi cosa ho fatto di sbagliato, non sono bravo con queste cose.
Soluzione
Prendendo in prestito una tecnica per abbinare stringhe tra virgolette, rimuovi & amp;
dalla tua classe di caratteri, aggiungi un'alternativa per & amp;
non seguito da < codice> # e consenti alla stringa di terminare facoltativamente con & amp;
:
^ (? (: [.?! A-Za-z0-9 -', @: () $ # / \\] + | & amp; [^ #]) * & amp;) $
Altri suggerimenti
Lo farei effettivamente in due parti:
- Controlla il set di caratteri consentito. Per fare questo vorrei cercare personaggi che non sono ammessi e restituire false in caso di corrispondenza. Ciò significa che ho una bella espressione semplice:
[^ A-Za-z0-9' \ & amp; @:.?! () $ # ^]
- Controlla la sottostringa vietata. E poiché è solo una sottostringa, probabilmente non userei nemmeno una regex per quella parte.
Non hai menzionato la tua lingua, ma se in C #:
bool IsValid(string input)
{
return !( input.Contains("&#")
|| Regex.IsMatch(@"[^A-Za-z0-9'\.&@:?!()$#^]", input)
);
}
^ ((& amp; #) [A-Za-z0-9 -', & amp; @:.?! () $ # / \\]?!) * $
nota che l'ultimo \ è scappato (raddoppiato)
SO trasforma automaticamente \\
in \ se non in backtick
Supponendo che RegExp sia compatibile con Perl
Per non corrispondere sulla stringa '& amp; #':
(?! [^ & Amp;] * & amp; #) ^ ([A-Za-z0-9 -', & amp; @:. () $ # / \\?!] *) $
Anche se non hai bisogno della parentesi perché stai abbinando l'intera stringa.
Solo FYI, sebbene la regex di Ben Blank funzioni, è più complicata di quanto debba essere. Lo farei così:
^(?:[A-Za-z0-9-'.,@:?!()$#/\\]+|&(?!#))+$
Poiché ho usato un lookahead negativo anziché una classe di caratteri negata, la regex non ha bisogno di alcun aiuto aggiuntivo per abbinare una e commerciale alla fine della stringa.
Consiglio di usare due espressioni regolari in un condizionale:
if (string has sequence "&#")
return false
else
return (string matches sequence "A-Za-z0-9-'.,&@:?!()$#/\")
Credo che il tuo secondo " principale " regex di
^([A-Za-z0-9-'.,&@:?!()$#/\])^[A-Za-z0-9-'.,&@:?!()$#/\\]+$
quot;
ha diversi errori:
- Testerà solo un personaggio nel tuo set
- Il carattere
\
nelle espressioni regolari è un token che indica che il carattere successivo fa parte di una sorta di "classe" di caratteri (es.\ n
= è il carattere di avanzamento riga). La sequenza di caratteri\]
sta effettivamente facendo sì che il tuo elenco tra parentesi non venga chiuso.
Potrebbe essere meglio usare
<*>Nota che il carattere barra è rappresentato da una doppia barra.
Il carattere +
indica che almeno un carattere da testare deve corrispondere al regex; se va bene passare una stringa di lunghezza zero, sostituire +
con un *
.