Regex per abbinare i simboli:! $% ^ & * () _ + | ~ - = `{} []:"; '<>?,. /


93

Sto cercando di creare un test Regex in JavaScript che testerà una stringa per contenere uno di questi caratteri:

!$%^&*()_+|~-=`{}[]:";'<>?,./

Maggiori informazioni se sei interessato :)

È per un'applicazione di modifica della password piuttosto interessante su cui sto lavorando. Se sei interessato, ecco il resto del codice.

Ho una tabella che elenca i requisiti della password e mentre gli utenti finali digitano la nuova password, testerà un array di Regex e metterà un segno di spunta nella riga della tabella corrispondente se ... controlla :) Devo solo aggiungere questo al posto del 4 ° elemento nella validationmatrice.

var validate = function(password){
    valid = true;

    var validation = [
        RegExp(/[a-z]/).test(password), RegExp(/[A-Z]/).test(password), RegExp(/\d/).test(password), 
        RegExp(/\W|_/).test(password), !RegExp(/\s/).test(password), !RegExp("12345678").test(password), 
        !RegExp($('#txtUsername').val()).test(password), !RegExp("cisco").test(password), 
        !RegExp(/([a-z]|[0-9])\1\1\1/).test(password), (password.length > 7)
    ]

    $.each(validation, function(i){
        if(this)
            $('.form table tr').eq(i+1).attr('class', 'check');
        else{
            $('.form table tr').eq(i+1).attr('class', '');
            valid = false
        }
    });

    return(valid);

}

Sì, c'è anche la corrispondente convalida lato server!


9
È abbastanza divertente che la risposta alla tua domanda si trovi nel titolo, ad eccezione dei caratteri speciali di escape e dell'inclusione di barre in avanti.
sciritai

1
Perché non usare .addClass("check")e .removeClass("check")? E vedere if (someBoolean == true)in codice mi fa sempre rabbrividire. Fallo e basta if (someBoolean). O, meglio ancora, fallo e basta $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;.
gilly3

+1 @ gill3 thx per la revisione del codice - ottimo feedback davvero. In passato ho sicuramente usato quei metodi a mano breve.
pixelbobby

@ gilly3, sembra funzionare alla grande in FF ma! IE8. amo questa mano corta. Sto cercando di capire cosa sta facendo IE8 in modo diverso.
pixelbobby

Risposte:


171

L'espressione regolare per questo è davvero semplice. Usa solo una classe di caratteri. Il trattino è un carattere speciale nelle classi di caratteri, quindi deve essere il primo:

/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/

È inoltre necessario eseguire l'escape degli altri metacaratteri delle espressioni regolari.

Modifica: il trattino è speciale perché può essere utilizzato per rappresentare un intervallo di caratteri. Questa stessa classe di caratteri può essere semplificata con intervalli a questo:

/[$-/:-?{-~!"^_`\[\]]/

Ci sono tre intervalli. "$" a "/", ":" a "?" e "{" a "~". l'ultima stringa di caratteri non può essere rappresentata più semplicemente con un intervallo:! "^ _` [].

Utilizzare una tabella ACSII per trovare gli intervalli per le classi di caratteri.


Perché non vengono menzionati i quantificatori \ Q e \ E per l'escape della sequenza di caratteri?
SerG

Prima di trovare questa soluzione stavo seguendo il percorso di esclusione della classe di caratteri: abbina tutto MA alfa, cifre, spazio bianco, ecc.
Pete Alvin

1
È risaputo che i trattini devono venire prima? Ho letto dozzine di risposte SO e cheat sheet regex, questa è la prima volta che ne ho sentito parlare. La tua risposta mi ha risparmiato molto dramma. Grazie!
CF_HoneyBadger

2
@SerG \Qe \Enon funzionano nel motore JS RegExp :(/^\Q.\E$/.test('Q+E'); // true
Paul S.

1
La barra rovesciata @ q4w56 non è nel set di caratteri specificato nella domanda originale, quindi la barra rovesciata non corrispondente è corretta. :)
Jeff Hillman

5

Il modo più semplice e più breve per ottenere questo risultato:

/[^\p{L}\d\s@#]/u

Spiegazione

[^...] Trova la corrispondenza con un singolo carattere non presente nell'elenco seguente

  • \p{L} => corrisponde a qualsiasi tipo di lettera di qualsiasi lingua

  • \d => corrisponde a una cifra da zero a nove

  • \s => corrisponde a qualsiasi tipo di carattere invisibile

  • @# => @e #caratteri

Non dimenticare di passare il uflag (unicode).


non avresti bisogno di un ^ per indicare di no?
Webber

1
@Webber No. Sono nella capitale e questo rende l'affermazione negativa. ^è necessario quando usiamo \we \sin lettere minuscole.
AmirZpr

3
Questo non lo interpreta in modo che sia esterno wche esterno s, e dal momento che quei due non si intersecano realmente, lascia passare tutti i personaggi? (Quindi non filtra nulla.)
Zael

2
@Zael Hai ragione, l'espressione regolare come dichiarato ( /[\W\S]/) lascia passare tutto. Sarebbe una rappresentazione più accurata di ciò che credo che Amir stesse ottenendo [^\w\s]. Nel primo, l'espressione regolare sta dicendo "trova tutto ciò che non è alfanumerico OR che non è uno spazio bianco", che come hai detto fa passare tutto poiché i caratteri alfanumerici non sono spazi bianchi e viceversa. Quest'ultimo dice "trova tutto ciò che non è alfanumerico E che non è uno spazio bianco". Naturalmente, si applicano eccezioni in quanto i caratteri accentati (come À) sono abbinati da [^\w\s].
Jesse

questo non include il carattere _
MikeSchem

4

Risposta

/[\W\S_]/

Spiegazione

Questo crea una classe di caratteri rimuovendo i caratteri della parola, i caratteri dello spazio e aggiungendo di nuovo il carattere di sottolineatura (poiché il carattere di sottolineatura è un carattere "parola"). Tutto ciò che resta sono i caratteri speciali. Le lettere maiuscole rappresentano la negazione delle loro controparti minuscole.

\Wselezionerà tutti i caratteri non "parola" equivalenti a [^a-zA-Z0-9_]
\Sselezionerà tutti i caratteri non "spazi vuoti" equivalenti a [ \t\n\r\f\v]
_selezionerà "_" perché lo neghiamo quando si usa il \We dobbiamo aggiungerlo di nuovo


MikeSchem, mi hai appena portato attraverso una macchina del tempo.
pixelbobby

sì, l'ho notato. era vecchio, ma sentivo che la risposta più semplice non era stata pubblicata.
MikeSchem

in che modo è diverso dalla risposta di seguito che non riesce con il trattino basso?
sf8193

sì, hai ragione, modificherò questo
MikeSchem

-1
// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflict
  const hasSpecial = password => {
    const specialReg = new RegExp(
      '^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',
    );
    return specialReg.test(password);
  };

Non usare il RegExpcostruttore quando puoi usare solo un'espressione regolare letterale. Molto meno lavoro in fuga (la maggior parte dei quali comunque non sono necessari), ed è anche più efficiente.
Bergi

Perché usare un lookahead complicato quando puoi semplicemente abbinare direttamente il personaggio?
Bergi

Puoi fare un esempio @Bergi? Non capisco cosa stai suggerendo.
Arni Gudjonsson

-1

Un modo semplice per ottenere questo risultato è l'insieme negativo [^ \ w \ s]. Questo essenzialmente cattura:

  • Tutto ciò che non è un carattere alfanumerico (lettere e numeri)
  • Tutto ciò che non è uno spazio, una tabulazione o un'interruzione di riga (indicati collettivamente come spazi bianchi)

Per qualche motivo [\ W \ S] non funziona allo stesso modo, non esegue alcun filtro. Un commento di Zael su una delle risposte fornisce una sorta di spiegazione.


No, manca il carattere di sottolineatura e tutti i caratteri fuori dall'intervallo ASCII e la maggior parte dei caratteri di controllo nell'intervallo ASCII corrisponderebbero a questa classe. /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Casimir et Hippolyte

-7

Sostituisci tutti gli ultimi da qualsiasi lingua in 'A' e se desideri, ad esempio, tutte le cifre su 0:

return str.replace(/[^\s!-@[-`{-~]/g, "A").replace(/\d/g, "0");

22
A quale domanda stai rispondendo?
Toto
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.