Регулярний вираз для відповідності символів:! $% ^ & * () _ + | ~ - = `{} []:"; '<>?,. /


93

Я намагаюся створити Regex-тест у JavaScript, який перевірятиме рядок, щоб містити будь-який із цих символів:

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

Більше інформації, якщо вас цікавить :)

Це для досить класної програми для зміни пароля, над якою я працюю. Якщо ви зацікавлені, ось інша частина коду.

У мене є таблиця, в якій перераховані вимоги до пароля, і, оскільки кінцеві користувачі вводять новий пароль, він перевірить масив регулярних виразів і поставить галочку у відповідному рядку таблиці, якщо це ... перевірить :) Мені просто потрібно додати цей замість 4-го елемента validationмасиву.

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

}

Так, існує також відповідна перевірка на стороні сервера!


9
Цілком смішно, що відповідь на ваше запитання лежить у назві, за винятком спеціальних символів та косих рисок.
sciritai

1
Чому б не використовувати .addClass("check")і .removeClass("check")? І бачення if (someBoolean == true)коду завжди змушує мене журитися. Просто зробіть if (someBoolean). Або, ще краще, просто зробіть $(".form table tr").eq(i+1).toggleClass("check", !!this); valid = valid && !!this;.
gilly3

+1 @ gill3 thx для перегляду коду - справді чудові відгуки. Я раніше використовував ці короткі методи.
pixelbobby

@ gilly3, здається, він чудово працює у FF, але! IE8. люблю цю коротку руку. Я намагаюся зрозуміти, що IE8 робить інакше.
pixelbobby

Відповіді:


171

Регулярний вираз для цього насправді простий. Просто використовуйте клас символів. Дефіс є спеціальним символом у класах символів, тому він повинен бути першим:

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

Вам також потрібно уникнути інших метасимволів регулярних виразів.

Редагувати: дефіс особливий, оскільки він може використовуватися для представлення діапазону символів. Цей самий клас символів можна спростити діапазонами до цього:

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

Є три діапазони. '$' до '/', ':' до '?' та '{' до '~'. останній рядок символів не може бути представлений простіше з діапазоном:! "^ _` [].

Використовуйте таблицю ACSII, щоб знайти діапазони для класів символів.


Чому не згадуються квантори \ Q та \ E для виходу з послідовності символів?
SerG

Перш ніж знайти це рішення, я йшов шляхом виключення класів персонажів: збігався з усім, АЛЕ алфавітом, цифрами, пробілами тощо
Піт Елвін

1
Чи загальновідомо, що дефіси повинні бути на першому місці? Я прочитав десятки відповідей на SO та шпаргалки регулярних виразів, це перше, про що я чув. Ваша відповідь врятувала мені багато драми. Дякую!
CF_HoneyBadger

2
@SerG \Qі \Eне працювати в двигуні JS RegExp :(/^\Q.\E$/.test('Q+E'); // true
Paul S.

1
Зворотна коса риса @ q4w56 не входить до набору символів, вказаних у вихідному питанні, тому неправильна зворотна коса риса є неправильною. :)
Джефф Хіллман, 02

5

Найпростіший і найкоротший спосіб досягти цього:

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

Пояснення

[^...] Зіставте один символ, якого немає у списку нижче

  • \p{L} => відповідає будь-якому листу будь-якої мови

  • \d => відповідає цифрі від нуля до дев'яти

  • \s => відповідає будь-якому виду невидимого символу

  • @# => @та #символи

Не забудьте передати uпрапорець (unicode).


чи не знадобиться вам ^ для позначення ні?
Веббер

1
@Webber Ні. Вони в столиці, і це робить твердження негативним. ^потрібен, коли ми використовуємо \wі \sмалими літерами.
AmirZpr

3
Хіба це не трактує так, що зовні wабо зовні s, і оскільки ці два насправді не перетинаються, це просто пропускає всіх символів? (Таким чином, нічого не фільтруючи.)
Заел,

2
@Zael Ви маєте рацію, регулярний вираз, як зазначено ( /[\W\S]/), все пропускає. Точнішим поданням того, на що, на мою думку, досягав Амір, було б [^\w\s]. У першому, регулярний вираз говорить "збігатися з усім, що не є буквено-цифровим АБО, що не є пробілами", що, як ви вже згадували, давайте все закінчимо, оскільки буквено-цифрові символи не є пробілами, і навпаки. Останній говорить: "збігайтеся з усім, що не є буквено-цифровим І що не є пробілами". Звичайно, винятки застосовуються в тому, що символи з наголосом (наприклад À) відповідають [^\w\s].
Джессі

сюди не входить _ char
MikeSchem

4

Відповідь

/[\W\S_]/

Пояснення

Це створює клас символів, що видаляє символи слова, пробіли та додає назад символ підкреслення (оскільки підкреслення є символом "слова"). Залишились лише спеціальні символи. Заголовні букви відображають заперечення нижчих регістрів.

\Wвибере всі символи, не еквівалентні "word" [^a-zA-Z0-9_]
\S, вибере всі символи, що не є "пробілами", еквівалентно [ \t\n\r\f\v]
_буде вибрати "_", тому що ми заперечуємо це при використанні \Wі потрібно додати його назад у


MikeSchem, ти щойно провів мене через машину часу.
pixelbobby

так, я це помітив. був старим, але я відчув, що найпростіша відповідь не була розміщена.
MikeSchem

чим це відрізняється від наведеної нижче відповіді, яка не вдається підкреслити?
sf8193

так, ти маєш рацію, я
зміню

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

Не використовуйте RegExpконструктор, коли ви можете просто використовувати літерал регулярного виразу. Набагато менше уникнення роботи (більшість з яких у будь-якому випадку непотрібна), а також вона є більш ефективною.
Берги

Навіщо використовувати складний пошук, коли ти можеш просто зіставити персонажа безпосередньо?
Берги

Чи можете ви навести приклад @Bergi? Я не розумію, що ви пропонуєте.
Арні

-1

Простим способом досягнення цього є від’ємна множина [^ \ w \ s]. Це по суті ловить:

  • Все, що не є буквено-цифровим символом (літери та цифри)
  • Все, що не є пробілом, вкладкою чи розривом рядка (разом називаються пробілами)

З якоїсь причини [\ W \ S] працює не однаково, не виконує жодної фільтрації. Коментар Заела до однієї з відповідей дає щось своє пояснення.


Ні, підкреслення відсутнє, і всі символи поза діапазоном ascii та більшість контрольних символів у діапазоні ascii відповідали б цьому класу. /[^\w\s]/.test('é') # true, /[^\w\s]/.test('_') # false.
Казимир та Іпполіт

-7

Замініть усі слова з будь-якої мови на 'A', і якщо ви хочете, наприклад, усі цифри на 0:

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

22
На яке питання ви відповідаєте?
Тото
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.