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

93

J'essaie de créer un test Regex en JavaScript qui testera une chaîne pour contenir l'un de ces caractères:

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

Plus d'informations si vous êtes intéressé :)

C'est pour une application de changement de mot de passe assez cool sur laquelle je travaille. Au cas où vous seriez intéressé, voici le reste du code.

J'ai un tableau qui répertorie les exigences en matière de mot de passe et lorsque les utilisateurs finaux tapent le nouveau mot de passe, il testera un tableau d'expressions régulières et placera une coche dans la ligne de tableau correspondante si cela ... vérifie :) Je dois juste ajouter celui-ci à la place du 4ème élément du validationtableau.

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);

}

Oui, il existe également une validation côté serveur correspondante!

pixelbobby
la source
9
C'est assez drôle que la réponse à votre question se trouve dans le titre, à l'exception de l'échappement des caractères spéciaux et des barres obliques.
sciritai
1
Pourquoi ne pas utiliser .addClass("check")et .removeClass("check")? Et voir if (someBoolean == true)dans le code me fait toujours grincer des dents. Fais juste if (someBoolean). Ou, mieux encore, faites simplement $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;.
gilly3
+1 @ gill3 merci pour la révision du code - un excellent retour en effet. J'ai déjà utilisé ces méthodes abrégées dans le passé.
pixelbobby
@ gilly3, il semble fonctionner très bien dans FF mais! IE8. J'adore ce raccourci. J'essaie de comprendre ce que fait IE8 différemment.
pixelbobby

Réponses:

171

L'expression régulière pour cela est vraiment simple. Utilisez simplement une classe de caractères. Le trait d'union est un caractère spécial dans les classes de caractères, il doit donc être le premier:

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

Vous devez également échapper aux autres métacaractères d'expression régulière.

Edit: Le trait d'union est spécial car il peut être utilisé pour représenter une plage de caractères. Cette même classe de caractères peut être simplifiée avec des plages à ceci:

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

Il existe trois gammes. '$' à '/', ':' à '?' et '{' à '~'. la dernière chaîne de caractères ne peut pas être représentée plus simplement avec une plage:! "^ _` [].

Utilisez une table ACSII pour rechercher des plages de classes de caractères.

Jeff Hillman
la source
Pourquoi les quantificateurs \ Q et \ E ne sont-ils pas mentionnés pour échapper à la séquence de caractères?
SerG
Avant de trouver cette solution, je suivais la route d'exclusion des classes de caractères: correspond à tout MAIS alpha, chiffres, espace blanc, etc.
Pete Alvin
1
Est-il notoire que les traits d'union doivent venir en premier? J'ai lu des dizaines de réponses SO et de feuilles de triche regex, c'est la première que j'en ai entendu parler. Votre réponse m'a sauvé beaucoup de drame. Merci!
CF_HoneyBadger
2
@SerG \Qet \Ene fonctionne pas dans le moteur JS RegExp :(/^\Q.\E$/.test('Q+E'); // true
Paul S.
1
La barre oblique inverse @ q4w56 n'est pas dans le jeu de caractères spécifié dans la question d'origine, donc la non-correspondance est correcte. :)
Jeff Hillman
5

Le moyen le plus simple et le plus court pour y parvenir:

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

Explication

[^...] Correspond à un seul caractère non présent dans la liste ci-dessous

  • \p{L} => correspond à tout type de lettre de n'importe quelle langue

  • \d => correspond à un chiffre de zéro à neuf

  • \s => correspond à tout type de caractère invisible

  • @# => @et #caractères

N'oubliez pas de passer le udrapeau (unicode).

AmirZpr
la source
n'auriez-vous pas besoin d'un ^ pour indiquer non?
Webber
1
@Webber Non. Ils sont en majuscule et cela rend la déclaration négative. ^est nécessaire lorsque nous utilisons \wet \sen minuscules.
AmirZpr
3
Cela ne l'interprète-t-il pas de sorte que soit à l' wextérieur s, soit à l' extérieur , et puisque ces deux ne se croisent pas vraiment, cela laisse juste passer tous les personnages? (Ne filtrant donc rien.)
Zael
2
@Zael Vous avez raison, l'expression régulière comme indiqué ( /[\W\S]/) laisse tout passer. Une représentation plus précise de ce à quoi je pense qu'Amir voulait en venir [^\w\s]. Dans le premier cas, l'expression régulière dit «correspond à tout ce qui n'est pas alphanumérique OU qui n'est pas un espace», ce qui, comme vous l'avez mentionné, permet de tout passer puisque les caractères alphanumériques ne sont pas des espaces et vice versa. Ce dernier dit "correspond à tout ce qui n'est pas alphanumérique ET qui n'est pas un espace". Bien sûr, des exceptions s'appliquent dans la mesure où les caractères accentués (comme À) sont mis en correspondance [^\w\s].
Jesse le
cela n'inclut pas le _ char
MikeSchem
4

Répondre

/[\W\S_]/

Explication

Cela crée une classe de caractères en supprimant les caractères de mot, les caractères d'espacement et en rajoutant le caractère de soulignement (car le trait de soulignement est un caractère "mot"). Il ne reste que les caractères spéciaux. Les lettres majuscules représentent la négation de leurs équivalents minuscules.

\Wsélectionnera tous les caractères non "mot" équivalents à [^a-zA-Z0-9_]
\S"sélectionnera tous les caractères non" espaces "équivalents à [ \t\n\r\f\v]
_" _ "car nous l'annulons lors de l'utilisation de \Wet nous devons le rajouter dans

MikeSchem
la source
MikeSchem, vous venez de me faire découvrir une machine à remonter le temps.
pixelbobby
oui, je l'ai remarqué. était vieux, mais je sentais que la réponse la plus simple n'était pas publiée.
MikeSchem
en quoi est-ce différent de la réponse ci-dessous qui échoue sur le trait de soulignement?
sf8193
oui, vous avez raison, je vais modifier ceci
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);
  };
Arni Gudjonsson
la source
N'utilisez pas le RegExpconstructeur lorsque vous pouvez simplement utiliser un littéral regex. Beaucoup moins de travail qui s'échappe (dont la plupart sont de toute façon inutiles), et c'est aussi plus efficace.
Bergi
Pourquoi utiliser une anticipation compliquée alors que vous pouvez simplement faire correspondre le personnage directement?
Bergi
Pouvez-vous donner un exemple @Bergi? Je ne comprends pas ce que vous suggérez.
Arni Gudjonsson
-1

Un moyen simple d'y parvenir est l'ensemble négatif [^ \ w \ s]. Cela attrape essentiellement:

  • Tout ce qui n'est pas un caractère alphanumérique (lettres et chiffres)
  • Tout ce qui n'est pas un espace, une tabulation ou un saut de ligne (collectivement appelés espace blanc)

Pour une raison quelconque, [\ W \ S] ne fonctionne pas de la même manière, il n'effectue aucun filtrage. Un commentaire de Zael sur l'une des réponses fournit une explication.

Harfel Jaquez
la source
Non, le trait de soulignement est manquant et tous les caractères hors de la plage ascii et la plupart des caractères de contrôle de la plage ascii correspondraient à cette classe. /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Casimir et Hippolyte
-7

Remplacez tous les derniers de n'importe quelle langue dans 'A', et si vous souhaitez par exemple tous les chiffres à 0:

return str.replace(/[^\s!-@[-`{-~]/g, "A").replace(/\d/g, "0");
Yaron Landau
la source
22
A quelle question répondez-vous?
Toto