Лучший способ написать это регулярное выражение? Отрицательный прогноз

#php #regex

#php #регулярное выражение

Вопрос:

Я думаю, что у меня это работает по большей части, но мне было интересно, есть ли лучший способ написать это:

 /b(Word)(?!.*?</a>)(?!.*?>)b/
  

Я пытаюсь сопоставить Word, когда он НЕ связан, и он НЕ является частью тегов HTML (например <a href="" title="Word"> , не должен совпадать).

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

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

1. Зачем пытаться исправить то, что не сломано? Если он хорошо подходит (и вы пытались сопоставить его с некоторыми БЛИЗКИМИ совпадениями, чтобы убедиться), тогда я бы сказал, просто пойдите с ним. То, что вы просите, может быть написано десятками разных способов, в зависимости от личных предпочтений.

2. Рассматривали ли вы возможность не пытаться использовать регулярное выражение для этого, а вместо этого фактически анализировать HTML, а затем искать слово в текстовых элементах, которые не имеют ссылочных элементов в качестве родительских?

3. @DerrickTucker Ты правильно подметил. Я новичок в программировании и немного перфекционист, но если это сработает, его можно было бы использовать.

4. @Amber Я, честно говоря, не очень разбираюсь в синтаксическом анализе HTML. Есть ли какие-либо ресурсы, к которым вы могли бы направить меня? Спасибо!

5. @AdamCapriola simplehtmldom.sourceforge.net это полезный инструмент.

Ответ №1:

Класс отрицаемых символов, который вы ищете, это [^<>]* . Это пропустит любые границы тегов.

  /b(Word) (?! [^<>]*</a> | [^<]*>) b/x
  

Обратите внимание, что поиск </a> позволит регулярному выражению соответствовать, если в ссылке будет дополнительная разметка; например, выделенное жирным шрифтом <a>..<b>Word</b>..</a> слово не будет пропущено. (Проверка таких вещей требует гораздо больше усилий, чем предварительный просмотр.)

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

1. Спасибо, Марио, это отлично!! И спасибо за информацию о более сложном примере. К счастью, я сомневаюсь, что столкнусь с подобными проблемами. 🙂