24 апр. 2010 г.

Почему мое регулярное выражение не находит слова, начинающиеся со знака процента?

Автор: Рэймонд Чен.
Оригинал на английском: Why can't I get my regular expression pattern to match words that begin with %?

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


СовпадаетНе совпадает
%1%1b
:%1:x%1

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




ШаблонСтрокаПредположениеРезультат
\b%1\b%1СовпадаетНе совпадает
\b%1\b:%1:СовпадаетНе совпадает
\b%1\bx%1Не совпадаетСовпадает
^..$%1СовпадаетСовпадает

Последняя запись - проверка работоспособности тестового приложения - важный шаг при отслеживании проблемы. Сперва надо убедиться в том, что проблема именно там, где вы предполагаете. Если шаблон ^..$ не работает, дело не в регулярном выражении, а в другой части программы.
"Оператор \b не работает?"
Нет, оператор \b работает превосходно. Проблема в том, что оператор \b делает не то, что вы думаете.
Для тех, кто не очень хорошо знаком с такой формой записи, поясню. Во-первых, вы можете быть озадачены тем, что \b присутствует в исходном вопросе и не встречается до сих пор. Оператор \w совпадает с буквой от A до Z (строчными и прописными), цифрой от 0 до 9 или знаком подчеркивания (На самом деле все гораздо сложнее, но приведенное описание хорошо подходит для нашего случая). \W, напротив, совпадает с любым другим символом. В терминах регулярных выражений, "слово" - это ближайшая строка, состоящая из символов \w. В заключение скажу, что оператор \b совпадает с местом между \w и \W, при этом начало и конец строки рассматриваются как невидимые \W.
Вернемся к исходному регулярному выражению \b%1\b. Обратите внимание, знак процента не входит в набор символов, которые совпадают с \w. Следовательно, для совпадения с первым \b, перед знаком процента должен быть символ \w. Здесь \b находится между \w и \W. Шаблон \b%1\b означает "\w, знак процента, единица, \W".
Строку "%1" можно записать в следующем виде:



\WНачало строки (воображаемое)
\W%
\w1
\WКонец строки (воображаемый)

Один оператор \b соответствует месту между знаком процента и единицей, а второй - месту между единицей и концом строки, но перед знаком процента \b нет, так как здесь по обоим сторонам находятся \W.
Изначально была поставлена неверная задача: написать регулярное выражение для поиска слова, которое начинается со знака процента. Однако это затруднительно, поскольку нет таких слов, которые начинаются со знака процента. Знак процента не совпадает с \w и, следовательно, не может быть частью слова.
Для поиска искомой строки больше подходит регулярное выражение (?<!\w)%1\b, означающее "знак процента, перед которым нет \w, и после которого следуют единица и \W".

Michael Kaplan
некоторое время назад также писал на эту тему
.

Комментариев нет:

Отправить комментарий