Почему моя конструкция RegExp не принята JavaScript? - PullRequest
1 голос
/ 25 марта 2009

Я использую RegExp для проверки ввода пользователя на веб-странице ASP.NET. Он предназначен для принудительного создания пароля (т. Е. Длиной от 8 до 20, хотя бы один символ верхнего регистра, хотя бы один символ нижнего регистра, хотя бы один номер, хотя бы один из символов # @! $% И не используется букв L или O (верхний или нижний) или цифр 0 и 1. Этот RegExp прекрасно работает в моем тестере (Expresso) и в моем коде C #.

Вот как это выглядит:

(?-i)^(?=.{8,20})(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])
(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]*$

(разрыв строки добавлен для форматирования)

Однако, когда я запускаю код, в котором он живет, в IE6 или IE7 (я не пробовал другие браузеры, так как это внутреннее приложение, а мы магазин Microsoft), я получаю сообщение об ошибке во время выполнения, в котором говорится: выражение». Вот и все - в сообщении об ошибке нет дополнительной информации, кроме номера строки.

Что в этом такого, что JavaScript не нравится?

Ответы [ 7 ]

5 голосов
/ 25 марта 2009

Ну, есть два способа определения регулярных выражений в Javascript:

а. Через конструктор объекта Regexp:

var re = new RegExp("pattern","flags");
re.test(myTestString);

б. Использование строкового литерала:

var re = /pattern/flags;

Следует также отметить, что JS не поддерживает некоторые принципы регулярных выражений. Полный список функций, не поддерживаемых в JS, можно найти на сайте регулярные выражения.info .

В частности, вы, кажется, устанавливаете некоторые флаги в выражении (например, флаг без учета регистра). Я бы предложил использовать флаг /i (как указано в синтаксисе выше) вместо использования (?-i)

Это сделало бы ваше регулярное выражение следующим образом (положительный взгляд в будущее поддерживается):

/^(?=.{8,20})(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]*$/i;

Для очень хорошей статьи на эту тему, посмотрите Регулярные выражения в JavaScript .

Редактировать (после комментария Говарда)


Если вы просто назначаете этот шаблон Regex для элемента управления RegularExpressionValidator, то у вас не будет возможности устанавливать параметры Regex (например, игнорировать регистр). Кроме того, вы не сможете использовать литеральный синтаксис Regex, поддерживаемый Javascript. Таким образом, единственный вариант, который остается, - сделать ваш шаблон по сути нечувствительным к регистру. Например, [a-h] должно быть записано как [A-Ha-h]. Извините, я бы сказал, что ваш Regex довольно скучный.

Вот решение этой проблемы, хотя я не могу ручаться за ее легитимность. Некоторые другие варианты, которые приходят на ум, могут заключаться в том, чтобы полностью отключить проверку на стороне Клиента и проверить только на Сервере. Это даст вам доступ ко всей версии Regex, реализованной объектом System.Text.RegularExpressions.Regex. В качестве альтернативы, используйте CustomValidator и создайте свою собственную функцию JS, которая применяет совпадение с регулярным выражением, используя предложенные мной (и другими) шаблоны.

1 голос
/ 25 марта 2009

Как упоминает Цербер, (? -I) не поддерживается в регулярных выражениях JavaScript. Итак, вам нужно избавиться от этого и использовать / I. Следует иметь в виду, что не существует стандарта для синтаксиса регулярных выражений; в каждом языке он отличается, поэтому тестирование в чем-то, использующем механизм регулярных выражений .NET, не является действительным тестом того, как он будет работать в JavaScript. Вместо этого попробуйте найти ссылку на регулярные выражения JavaScript, такие как this .

Ваш матч, который ищет 8-20 символов, также недействителен. Это обеспечит наличие не менее 8 символов, но не ограничивает строку до 20, поскольку класс символов с оператором kleene-closure (*) в конце может соответствовать столько символов, сколько предусмотрено. Вместо этого вам нужно заменить * в конце на {8,20} и удалить его с начала.

var re = /^(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]{8,20}$/i;

С другой стороны, я не совсем уверен, почему вы хотите ограничить длину паролей, если не существует жесткого ограничения базы данных (которого не должно быть, поскольку вы не должны хранить пароли в виде простого текста в базе данных, но вместо этого хэширование их до чего-то фиксированного размера с использованием алгоритма безопасного хеширования с солью). И, как уже упоминалось, я не вижу причин, чтобы быть настолько ограниченным на набор символов, которые вы позволяете. Я бы порекомендовал что-то вроде этого:

var re = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[#@!$%])[a-zA-Z0-9#@!$%]{8,}$/i;

Кроме того, с чего бы вам запрещать 1, 0, L и O из ваших паролей (и, похоже, вы пытаетесь запретить и I, о котором вы забыли упомянуть)? Это затруднит создание хороших паролей, и, поскольку вы никогда не видите пароль при его вводе, нет причин беспокоиться о письмах, которые выглядят до смешного похожими. Если вы хотите иметь более разрешительное регулярное выражение:

var re = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[#@!$%]).{8,}$/i;
1 голос
/ 25 марта 2009

Я не знаком с синтаксисом регулярных выражений в C #, но так ли это (в начале)

(?-i)

означало включить модификатор шаблона нечувствительности к регистру? Если так, то это твоя проблема. Javascript не поддерживает указание модификаторов шаблона в выражении. Есть два способа сделать это в javascript

var re = /pattern/i
var re = new RegExp('pattern','i');

Дайте одному из них попробовать, и ваше выражение лица должно быть счастливым.

0 голосов
/ 26 марта 2009

(?-i) должен выключить нечувствительность к регистру . Все, кажется, предполагают, что вы пытаетесь включить на , но это будет (?i). В любом случае, вы не хотите, чтобы он был без учета регистра, поскольку вам нужно убедиться, что в нем есть как прописные, так и строчные буквы. Поскольку сопоставление с учетом регистра используется по умолчанию, вводить регулярное выражение с (?-i) бессмысленно даже в тех вариантах (например, .NET), которые поддерживают встроенные модификаторы.

0 голосов
/ 25 марта 2009

Я бы использовал это регулярное выражение:

/(?=[^2-9]*[2-9])(?=[^a-hj-km-np-z]*[a-hj-km-np-z])(?=[^A-HJ-KM-NP-Z]*[A-HJ-KM-NP-Z])(?=[^#@!$%]*[#@!$%])^[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]{8,}$/

[^a-z]*[a-z] обеспечит соответствие как можно раньше вместо расширения .* и делает возвращение.

0 голосов
/ 25 марта 2009

(- я)

Не существует в JS Regexp . Флаги могут быть указаны как «новый RegExp (« pattern »,« i »)» или буквальный синтаксис «/pattern/iveloper.

(? = * * 1 010

Существует в современных реализациях JS Regexp, но опасно глючит в IE. По этой причине в JS следует избегать косвенных утверждений.

длиной от 8 до 20, хотя бы один символ верхнего регистра, хотя бы один символ нижнего регистра, хотя бы один номер, хотя бы один из символов # @! $% И не используйте буквы L или O (верхний или ниже) или цифры 0 и 1.

У вас есть для этого в RegExp, и у вас есть , чтобы поместить все условия в один RegExp? Потому что это простые условия для сопоставления с использованием нескольких регулярных выражений или даже простого сопоставления строк:

if (
    s.length<8 || s.length>20 ||
    s==s.toLowerCase() || s==s.toUpperCase() ||
    s.indexOf('0')!=-1 || s.indexOf('1')!=-1 ||
    s.toLowerCase().indexOf('l')!=-1 || s.toLowerCase().indexOf('o')!=-1 ||
    (s.indexOf('#')==-1 && s.indexOf('@')==-1 && s.indexOf('!')==-1 && s.indexOf('%')==-1 && s.indexOf('%')==-1)
)
    alert('Bad password!');

(Это действительно жестокие и бесполезные правила паролей, если они предназначены для конечных пользователей!)

0 голосов
/ 25 марта 2009

Вы заключаете регулярное выражение в / / символов?

var regexp = /[]/;
return regexp.test();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...