Schema Regex - Consenti alfanumerici, un gruppo di caratteri speciali, ma non una determinata sequenza di caratteri

StackOverflow https://stackoverflow.com/questions/429719

  •  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.

È stato utile?

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:

  1. 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; @:.?! () $ # ^]
  2. 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 * .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top