Статьи

Ответы на Эпизод 2 (Реальные регулярные выражения)

Да, я немного опоздал с публикацией этих ответов. Сожалею!

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

Как и на прошлой неделе, перед тем, как перейти к реальным ответам, пожалуйста, побалуйте себя, пока я немного понтифицирую:

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

К счастью, почти каждая реализация регулярных выражений имеет «подробный» режим, который позволяет встраивать комментарии в регулярные выражения (в большинстве языков это флаг x ). Ради тех, кто должен прочитать ваш код, пожалуйста, используйте подробный режим!

Хорошо, к ответам:

1. [A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}

Это телефонный номер в США , включая те, которые используют буквы (например, 831-555-CODE ). Переписанный в подробном режиме, он имеет больше смысла:

   [A-PR-Y0-9] {3} # Префикс кода города
   -
   [A-PR-Y0-9] {3} # 3-значный обмен
   -
   [A-PR-Y0-9] {4} # 4-значный суффикс

Бирман имел хороший обзор проблем с этим шаблоном :

[Это] не учитывает предыдущую 1, если код города указан в скобках, если группы цифр разделены точкой или пробелом вместо тире, или тот факт, что в сотовых телефонах есть Q и Z на них. Это также не гарантирует, что группа изолирована и не является частью чего-то вроде 1234888-234-123456123.

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

2. &(?!(w+|#d+);)

Это не ошибочная попытка сопоставить сущности HTML . На самом деле это шаблон, который будет сопоставлять амперсанды в HTML, которые не являются частью сущностей (он взят из шаблона шаблона Django fix_ampersands ).

Вот подробный режим:

   & # Подходим амперсанд ...
   (?! # ... то есть * не * сопровождается ...
     (
       w + # ... слово символов ...
       |  # ... или...
       # d + # ... числовые символы сущностей ...
     )
     ;  # ... и точка с запятой.
   )

«Проблема» с этим шаблоном довольно тонкая: он сопоставляет HTML-объекты, которые правильно сформированы и остаются недействительными (например, &#ggxy; ). Так что в качестве способа поиска не закодированных амперсандов это просто прекрасно, но если вы захотите использовать его как часть валидатора HTML, это будет неприемлемо.

3. (-?(?:0|[1-9]d*))(.d+)?([eE][-+]?d+)?

Большинство читателей получили это; это число с плавающей запятой IEEE с необязательным показателем степени. В подробном режиме:

   (# Нефракционная часть базы
     -?  # может быть ведущим отрицательным знаком 
     (?: # Несоответствующая группа ...
       0 | [1-9] d * # 0 или несколько цифр
     )  
   )
   (.D +)?  # Десятичная точка и дробная часть базы
   (# Экспонент
     [eE] # 
     [- +]?  #> «е», плюс или минус, показатель степени.
     д + # /
   )?

Некоторые читатели думали, что d в базовой части — ошибка; на самом деле это не так — это выражение соответствует либо 0 , либо числу, которое начинается с 1-9, а затем содержит любые цифры.

Фактическая ошибка заключается в том, что этот шаблон соответствует ненормализованным числам (т. 123.45e3 , что более правильно должно быть записано как 1.2345e5 ).

4. ([da-f]{2}:){5}([da-f]{2})

Почти каждый получил это: это MAC-адрес :

   ([da-f] {2}:) {5} # Две шестнадцатеричные цифры, за которыми следует двоеточие, x5
   ([da-f] {2}) # Две шестнадцатеричные цифры до конца.

Как отметил Бирман , этот шаблон не соответствует нескольким другим формам, разрешенным для MAC-адресов; они могут быть написаны с дефисами ( 12-34-56-78-9A-BC ), или как пунктирные 1234.5678.9ABC ( 1234.5678.9ABC ).

5. <[^>]*?>

Этот также, казалось, был легок для большинства читателей; он соответствует любому тегу SGML . В подробном синтаксисе:

   <# Запустите тег
   [^>] *?  # Любой не-gt символ
   > # Конец тега

«Ошибка» в этом немного более абстрактна: неправильно сформированный SGML / HTML сильно испортит ее. Однако я оставлю поиск такого кода упражнением для читателя.

В следующий раз

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

Увидимся завтра!