PHP регулярное выражение для соответствия HTML код с использованием группы захвата - PullRequest
1 голос
/ 18 февраля 2020

Я застрял, пытаясь написать регулярное выражение в PHP, которое соответствует тегам HREF с использованием групп захвата.

Мой текущий код выглядит следующим образом:

$content = preg_replace_callback(
  '/<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>([^<]*)<\/a>/i',
    function($m) {
...

Код отлично работает для всего этого:

<a href="/go/bla" rel="sponsored noopener" target="_blank">Test link</a>

Но у меня есть несколько URL, которые выглядят так - обратите внимание на вложенные <span></span>:

<a href="/go/bla" rel="sponsored noopener" target="_blank"><span>Test link</span></a>

Моя вторая группа захвата соответствует ^ <, поэтому она не совпадает. Я пытался изменить группу, чтобы соответствовать чему-либо, НО. Вот где я потерпел неудачу, из-за отсутствия опыта в регулярных выражениях:) </p>

Может ли какой-нибудь эксперт по регулярным выражениям указать мне правильное направление?

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Этого должно быть достаточно для вашего примера.

<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>(?:<[^>]+>)?([^<]*)(?:<[^>]+>)?<\/a>

Добавление (?:<[^>]+>)? будет соответствовать дополнительным тегам, если они существуют.

Смотрите это в действии здесь .

0 голосов
/ 19 февраля 2020

Текущее регулярное выражение должно помочь вам:

<a[^>]*href=["|\']([^"|\']*)["|\'][^>]*>(?:<[^>]+>)*([^<]*)(?:</[^>]+>)*<\/a>

Это будет соответствовать вашему примеру, а также этому примеру:

<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test link</h1></span></a>

Однако как насчет этого?

<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test <span>link</span></h1></span></a>

Неа! Это ломается. И теперь нам нужно будет go вернуться назад и обернуть свои мысли вокруг тегов внутри тегов с текстом вне этих тегов, чтобы все еще соответствовать, нам придется еще немного разбить его. На этом этапе было бы лучше просто получить список всех тегов a, а затем выполнить некоторые подстановки для извлечения необходимых данных после факта.

$matches = preg_match_callback('/<a[^>]*?href=(.*?")[^>]*?>(.*?)</a>/i', function($m) {
  ... more regexes
}

Может быть, лучше рассмотреть используя библиотеку, которая позволяет вам загружать html контент как объекты (во многом как в браузере) и запрашивать результаты, используя что-то вроде xpath.

В PHP вы можете использовать DOM и XPath для загрузки html. Ниже приведен пример.

$doc = new DOMDocument();
$html = <<<EOD
<html>
<body>
<a href="/go/bla" rel="sponsored noopener" target="_blank">Test link</a>
<a href="/go/bla" rel="sponsored noopener" target="_blank"><span>Test link</span></a>
<a href="/go/bla" rel="sponsored noopener" target="_blank"><span><h1>Test <span>link</span></h1></span></a>
</body>
</html>
EOD;

$doc->loadHTML($html);
$xpath = new DOMXpath($doc);
$query = $xpath->query('//a');

if (!is_null($query)) {
    foreach ($query as $q) {
        print $q->getAttribute('href') . ' - ';
        print $q->nodeValue . "\n";
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...