Pull to refresh

Comments 48

Сколько этим пользовался, а только сегодня узнал, что они называются опережающие и ретроспективные )
Отдельное вам спасибо за уважение к русскому языку и попытку переода терминов. Хотя бы в заголовке.
Раз такое дело: мало кто знает ещё о так называемых «possessive quantifiers». При этом они предоставляют довольно интересное поведение.

Почитать: www.regular-expressions.info/possessive.html
В регулярках вообще много такого, что мало кто знает. В PCRE есть «глаголы» (VERBS), например. Про рекурсивные регулярки мало кто слышал почему-то и так далее.
Смею предположить потому, что всегда проще написать две регулярки последовательно, вместо того, чтобы ломать мозг потенциальному поддерживателю кода.
Это как сказать. Например, глагол «UCP» (так кажется, могу путать) нужен для корректной работы с UTF-8.
Чтобы использовать магическое слово «UCP» — не обязательно знать про «VERBS в PCRE», правда?
Собеседовал недавно человека, решаем задачку… Он в конце регулярного выражения ставит модификаторы isU

Спрашиваю «А зачем они нужны и что значат»?
Ответ — «Не знаю, они нужны чтобы все правильно работало, всегда их ставлю»
Смешно, конечно.

Но я себя заставлял разбираться в PCRE года через три, после того, как начал пользоваться всякими регулярками. Просто болк — он педант, он шагу не ступит, пока не проверит поле вокруг на триста миль вперед на отсутствие мин. Это очень ценное качество, но оно не всем дано.

Я не про модификаторы, я про «глаголы».
Неправильно. UCP — это и есть VERBS. Применяется он, например, так: /(*UCP)\w+/.
Я знаю, как он применяется, спасибо.

Это никак не отменяет тезис «увидел на стаковерфло, и повторил», правда?

Рекурсивное регулярное выражение — это уже не регулярное выражение, а стековая машина. Это не делает их менее полезными, но важно понимать, что это уже не конечный автомат.
Рекурсивное регулярное выражение — это всё ещё регулярное выражение, пусть и не автомат. Где есть требование делать их конечным автоматом?
Классическое использование термина «регулярное выражение» означает «выражение, описывающее некоторый регулярный язык». Это, как мы видим, не всегда так, но мою чуткую душу это коробит, так что вот и напоминаю.
Я много раз читал про рекурсивные регулярки, но мне так ни разу не попалась в жизни возможность ими воспользоваться. Зачем они? :)
Например, мне как-то нужно было матчиться на функцию, в которую могла быть вложена другая функция. Что-то вроде sin(cos(0.3))
Ну так с ходу если максимальный уровень вложенности известен и он не больше двух то можно и без рекурсивок обойтись.
Простите за банальность, но традиционно, про html и регекспы
Вас спасает надежда на то, что пользователь не будет злоупотреблять, но вообще когда-нибудь оно обязательно сломается ;)
Да, именно на этот вопрос я натыкался когда столкнулся с проблемой.
Но в данном случае пользователь — только я, и я не склонен ломать свой сайт ;-)
Хорошая книга, тоже рекомендую, даже не жалко бумаги на бумажный вариант.
Может лучше было использовать Markdown или другой движок? Пусть заморочка с абзацами (два пробела в конце строки или одна пустая), но зато готовый набор множества других «плюшек»
Ага. Здравствуй, бухгалтер, теперь ты пишешь на маркдауне.
Неа. Здравствуй, бухгалтер, теперь ты пишешь на HTML. Бухгалтеру необязательно говорить, что две решетки перед заголовком это «MARKDOWN».
Но вообще я согласен. Даже заморочка с абзацами и переносами для некоторых целевых групп неприемлемы.
Изначально(лет 10 назад) на том сайте так и было, но с течением времени оказалось, что обычный HTML проще и удобнее.
Markdown у всех разный, а HTML — везде один :-)
HTML тоже разнится (я о кроссбраузерности). Хотя в данном случае набор поддерживаемых тегов подразумевается ограниченный весьма?
Да, как на хабре. Никаких css, и прочих радостей жизни.
Мне кажется, что стоит упомянуть, что данные проверки относятся к так называемым «позиционным» проверкам, т.е. они совпадают не с текстом, а с позицией в тексте. При этом текст не «поглощается», что позволяет матчить его другой частью регулярного выражения.
Можно еще вспомнить, что опережающие проверки можно использовать перед искомым выражением (там, где обычно пишут условия для ретроспективной проверки) для имитации логического оператора «И» в регулярных выражениях. Например,
(?=.*\d)(?=^[A-Z]).{8,}
будет искать строки длиной не менее 8 символов, в которых есть хотя бы одна цифра И которые начинаются с прописной латинской буквы.
Есть еще редко используемый модификатор — x. Он позволяет писать комментарии и игнорирует переносы строк:

$str = 'test-pcre-comments76755';
preg_match('
	~
	^      #начало строки
	(\w+)  #слово
	.+?    #любая последовательность (не жадная)
	(\d+)  #число
	$      #конец строки
	~x
', $str, $matches);
var_dump($matches);

array
  0 => string 'test-pcre-comments76755' (length=23)
  1 => string 'test' (length=4)
  2 => string '76755' (length=5)
Наверное стоило так же упомянуть, что есть так же разные диалекты (в одном из них эти проверки не работаю), которые используют разные языки. К примеру в JS ретроспективная проверка не работает :). Я сейчас уже не помню, всех тонкостей, но их много
C Look-ahead в JS не сталкивался, чаще требуется look-behind. Был разочарован, когда пол-часа долбился с написанием правила для такой проверки, и удивлялся, почему не работает. Оказалось что просто JS не поддерживает ее.
Назовите хотя бы одну причину, почему не надо использовать нормальный html парсер, а пользоваться регексами, которыми невозможно нормально парсить context-free grammar?
Причина проста: гвозди забивают молотком, а не микроскопом.

Именно парсить HTML (выкусывать ссылки, картинки и прочее) — конечно стоит парсером.
Заменять переводы строк — можно тем, что работает проще, быстрее и не требует поддержки.
Бред. Имеет смысл только для написанных на коленке приложениях для себя, или для очень небольших объемов html. Регексы, особенно чужие — write-only код, со всеми вытекающими.
Еще раз — я не предлагаю выдирать урлы картинок регэкспорм — хотя это и можно сделать.
Регулярные выражения в 20 символов для простых задач — проще и понятнее, чем парсер.
С некоторых пор пользуюсь Jevix в своих проектах — очень доволен!

Практически забыл про оформление текстов. Вы, кстати, тоже им пользуетесь, прямо сейчас, на Хабре.
Вместо регэкспов можно спокойно использовать стандартную функцию nl2br
Такое выражение поломается
<ul>
<li></li>
<li></li>
</ul>
В Perl еще есть нечасто используемый ключик e, который позволяет запускать код Perl и использовать возвращаемое значение в подстановке:

# Преобразовываем urlencoded строки в читаемые utf8
s/ ( (?: %[0-9A-F]{2} )+ )/ { my $a1 = uri_unescape($1); utf8::decode($a1); $a1; } /gex;
Only those users with full accounts are able to leave comments. Log in, please.