Использование регулярного выражения для проверки данных является правильным или нет? - PullRequest
7 голосов
/ 18 июля 2010

Я нашел несколько статей и постов, в которых предлагается не использовать регулярные выражения для проверки пользовательских данных. Я не уверен во всех вещах, но я обычно нахожу это в случае подтверждения адреса электронной почты.

Итак, я хочу уточнить, хорошо ли использовать регулярное выражение для проверки пользовательского ввода или нет? если это хорошо, то что плохого в проверке адреса электронной почты?

Edit:

Таким образом, мы можем сказать, что для базовой первичной проверки типов данных мы можем использовать регулярное выражение, и это хорошо, а для полной проверки нам нужно объединить его с другим анализатором.

И для второй части для проверки электронной почты в общем использовании мы можем использовать это, но согласно стандарту это не подходит. Это?

Теперь путаница в выборе правильного ответа

Ответы [ 8 ]

4 голосов
/ 18 июля 2010

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

Это плохо, потому что регулярные выражения могут быть сложными, и вы многое можете сделать неправильно.


Редактировать Ну и ладно. Вот несколько реальных советов: во-первых, убедитесь, что ожидаемые действительные значения могут быть выражены с помощью регулярного выражения вообще. То есть когда язык допустимых значений - обычный язык . В противном случае вы просто не сможете использовать регулярные выражения (или, по крайней мере, не только регулярные выражения)!

Теперь, когда мы знаем, что может быть проверено с помощью регулярных выражений, мы должны обсудить, что может быть проверено с помощью регулярных выражений. Если мы возьмем в качестве примера адрес электронной почты (как и многие другие), мы должны знать, как может выглядеть действительный адрес электронной почты (см. RFC 5322):

addr-spec       =   local-part "@" domain
local-part      =   dot-atom / quoted-string / obs-local-part
domain          =   dot-atom / domain-literal / obs-domain
domain-literal  =   [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
dtext           =   %d33-90 /          ; Printable US-ASCII
                    %d94-126 /         ;  characters not including
                    obs-dtext          ;  "[", "]", or "\"

Здесь мы видим, что local-part может состоять из цитируемой строки , которая может содержать любой печатный символ US-ASCII (исключая \ и " ", но включая @). Поэтому недостаточно проверить, содержит ли адрес электронной почты только один @, если мы хотим разрешить адреса в соответствии с RFC 5322.

С другой стороны, если мы хотим разрешить любой действительный адрес электронной почты в соответствии с RFC 5322, мы также разрешим адреса, которые, вероятно, не существуют или просто бессмысленны в большинстве случаев (например, ""@localhost).

3 голосов
/ 18 июля 2010

Ваш вопрос состоит из двух частей: (1) использование регулярных выражений для проверки правильности данных и (2) использование их для проверки правильности адресов электронной почты?

Re (1), это действительно зависитна ситуацию.Во многих ситуациях регулярное выражение будет более чем достаточно для проверки ввода пользователя;например, проверка того, что имя пользователя имеет только буквенно-цифровые символы.Когда набор регулярных выражений, вероятно, будет неадекватным, это когда входные данные могут быть переданы в нечто вроде запроса к базе данных или оператора eval ().В этих случаях могут существовать языковые конструкции, такие как рекурсия, которые не могут быть обработаны с помощью регулярных выражений, и, в более общем случае, вам потребуется что-то, что много знает о целевом языке, для проверки (и очистки).В большинстве случаев вы захотите экранировать ввод, чтобы на целевом языке это была безвредная строка.

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

2 голосов
/ 18 июля 2010

Регулярные выражения могут быть плохими по трем причинам:

  1. Они могут быть действительно сложными и, в конечном итоге, не поддерживаемыми.Делать ошибки очень легко.
  2. Существуют определенные типы текста, которые вообще нельзя анализировать с помощью регулярных выражений (например, HTML ).По сути, все с вложенными шаблонами не может быть проанализировано с помощью регулярных выражений.Например, вы не сможете проанализировать язык программирования с помощью regex.
  3. В зависимости от типа текста, с которым вы работаете, это может быть проще и понятнее, если вы просто напишите свой собственный код для его анализа..

Но если ни то, ни другое не является проблемой для того, с чем вы работаете, то нет ничего плохого в использовании регулярных выражений.Я бы сказал, что проверка адресов электронной почты - хорошее применение регулярных выражений.

1 голос
/ 18 июля 2010

Регулярные выражения - это инструмент, как и любой другой, хотя и очень мощный.

Они настолько сильны, что люди, использующие их, как правило, страдают от проблемы всего, что выглядит как гвоздь (когда у вас есть молоток). Это приводит к тому, что они используются в ситуациях, когда другой метод был бы более многословным, но более эффективным и более обслуживаемым.

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

Основные проблемы с ними включают в себя:

  • Запрещение плюсовых символов в первой половине адреса (несмотря на то, что они встречаются относительно часто)
  • Ограничение TLD тремя символами (это блокирует TLD .museum)
  • Ограничение ДВУ до двухсимвольных ДВУ с кодом страны или списка конкретных ДВУ (таким образом, вынуждая его обновлять всякий раз, когда в игру вступает новый ДВУ - угадайте, что никогда не произойдет?)

Адреса электронной почты настолько сложны, что регулярное выражение на самом деле не должно пытаться делать что-то большее:

  1. То, что не включает @
  2. An @
  3. То, что не включает @
  4. A .
  5. То, что не включает @
1 голос
/ 18 июля 2010

Если шаблон данных, которые вы проверяете, может быть выражен полностью и правильно с помощью регулярных выражений, вы можете безопасно их использовать, не беспокоясь. Однако не все текстовые шаблоны могут быть выражены с помощью регулярных выражений (например, контекстно-свободных грамматик). В таких случаях вам может потребоваться написать анализатор или пользовательский метод для проверки данных.

1 голос
/ 18 июля 2010

Для адресов электронной почты хорошо использовать регулярные выражения. Это будет работать в большинстве случаев.

В общем: вы должны проверять регулярными выражениями все, что можно выразить как регулярный язык

0 голосов
/ 19 июля 2010

Регулярные выражения не плохи для проверки большинства данных, если это обычный язык.

Но, как уже отмечалось, иногда их сложно поддерживать, и программисты вносят ошибки.

Самый простой способ смягчить ситуацию - использовать Tests / TDD. Эти тесты должны вызывать метод, который использует регулярное выражение для проверки адресов электронной почты (в настоящее время я использую это регулярное выражение /^[A-Z0-9._%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i, которое работает достаточно хорошо. Таким образом, когда вы получаете ложный положительный или ложный отрицательный результат, вы можете добавить другой тест для В этом случае скорректируйте свое регулярное выражение и убедитесь, что вы не нарушили какое-либо другое условие.

Если TDD кажется немного большим, такой инструмент, как Expresso, позволяет сохранять регулярные выражения с тестовыми данными, что может помочь в отслеживании значений, которые должны пройти / не пройдены, и поможет в создании и понимании вашего регулярного выражения.

ПРЕДУПРЕЖДЕНИЕ:

Позаботьтесь о создании регулярных выражений. Существует потенциал для внедрения уязвимостей ReDos

См .: http://msdn.microsoft.com/en-us/magazine/ff646973.aspx

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

0 голосов
/ 18 июля 2010

Проблемы, вероятно, связаны с тем фактом, что часто используемые регулярные выражения не охватывают все возможные (действительные) входные данные и / или ограничивают пользователя в том, что онможет вводить.

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

Возьмите номера кредитных карт.Вы должны рассмотреть способы, которыми пользователь может ввести их:

1234-5678
// or
1234 5678
// or
1234 - 5678

И теперь у вас есть две возможности:

  1. Вы ограничиваете ввод первым случаем, что приведет кболее простое выражение, но будет ограничивать (и, возможно, раздражать) пользователя наиболее.
  2. Вы создаете выражение, которое принимает любую из этих возможностей, что делает выражение более сложным (следовательно, сложнее в обслуживании), но более удобным для использования.

Это компромисс.

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