Опережающая проверка и dotall регулярное выражение

Рейтинг: 0Ответов: 1Опубликовано: 22.01.2015

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

Исходные данные:

Lorem <a data-smth-id="1" href="#">ipsum dolor sit amet</a>, consectetur adipiscing elit.
<a data-smth-id="2" href="#">Sed ut maximus turpis. In pulvinar pulvinar mattis.
Suspendisse dapibus</a> a orci eu suscipit.
<a id="smth_to_smw" href="#">In quis erat non nisl vehicula egestas.</a>
Etiam interdum semper cursus.

Есть следующее регулярное выражение: #<a(?!.\*id="smth\_to\_smw").\*>(.\*)</a>#iU

Этим выражением я хочу получить все элементы a, в которых отсутсвует id, указанный в регулярном выражении. И действительно, если содержание ссылки находится на одной строке, то всё работает как нужно. Вторую ссылку не находит по причине того, что символ точка в регулярном выражении по умолчанию равен всем символам, кроме символа переноса строки. Отсюда следует, что к регулярному выражению логично добавить флаг s (dotall), но после этого вместо ожидаемой работы регулярное выражение не находит вообще ничего. Может, кто знает, в чём проблема?

Ответы

▲ 3Принят

На этот случай есть такой трюк:

[\s\S]* - матчит все символы.

#<a(?!.*id="smth_to_smw").*>([\s\S]*)</a>#iU

На вашем тексте:

MATCH 1
1.  [35-55] `ipsum dolor sit amet`
MATCH 2
1.  [119-190]   `Sed ut maximus turpis. In pulvinar pulvinar mattis.
Suspendisse dapibus`

Посмотреть пример работы