Проверить, что фраза отсутствует в элементе <a>(или другом) - PullRequest
1 голос
/ 18 ноября 2009

Друг пишет сценарий рекламы, который размещает ссылки на отдельные фразы в HTML-коде.

Естественно, если фраза уже находится внутри элемента <a> (или другого элемента, который не позволяет этого - например, если фраза найдена в атрибуте элемента), он не хочет, чтобы скрипт выписывал ссылка как бы нарушившая валидацию.

Он спросил меня, что я думаю. После некоторой неуклюжести я спрашиваю всех, что вы думаете.

Просто, чтобы уточнить, вход представляет собой целую запись блога в HTML. Пример:

<p>This is a short blog post about ponies!</p>
<p>I have <a href="/ponies">written about ponies before</a>.</p>
<p><img src="/media/ponies.jpg" /></p>

В этом примере, скажем, я хочу заменить ponies (любой случай) на <a href="http://www.ponies.com">ponies</a> (но с исходным регистром).

Вывод сверху должен выглядеть следующим образом:

<p>This is a short blog post about <a href="http://www.ponies.com">ponies</a>!</p>
<p>I have <a href="/ponies">written about ponies before</a>.</p>
<p><img src="/media/ponies.jpg" /></p>

Нам не нужен полный код, но хорошие идеи / регулярные выражения приветствуются. Он пишет это на PHP, но не зависит от языка.

Ответы [ 2 ]

6 голосов
/ 18 ноября 2009

Используйте выражение XPath , которое находит текстовые узлы, содержащие требуемую строку, но только если они являются дочерними элементами допустимых элементов:

//p/text()[contains(.,'ponies')]

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

Используется для приведенного примера ввода, единственное совпадение - "This is a short blog post about ponies!". «Пони» в элементе <a> не совпадают, потому что это выглядит только для прямых потомков элементов <p>. Вы можете уточнить это, чтобы оно соответствовало другим элементам, таким как <div> s, или только определенным элементам <p> (например, с определенными классами).

Приятный бонус при использовании такого выражения XPath, как то, что оно будет возвращать только текстовые узлы. Это означает, что «пони» никогда не будут появляться рядом с какими-либо HTML-элементами, поэтому вы определенно можете безопасно использовать регулярные выражения после того, как XPath сделал свое дело, не вызывая гнева Ктулху.

XPath - это распространенный метод работы с XML и HTML. PHP имеет много библиотек XPath для вас на выбор. Скорее всего, вы уже используете библиотеку, которая работает с XPath.


Альтернативный метод - найти все текстовые узлы в документе HTML и отфильтровать их по их родителям. Результат точно такой же, но в зависимости от ваших требований этот способ может масштабироваться лучше:

//text()[parent::p and contains(.,'ponies')]

Это выражение выглядит так:

//text()                  # Find all text nodes in the document
    [parent::p            # whose parent is a "p" element
    and                   # and
    contains(.,'ponies')] # contains the string "ponies"
3 голосов
/ 18 ноября 2009

Извините, но я должен сказать

Разбор HTML Путь Ктулху

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...