找到匹配时获取数组的其他部分

Get other part of array when match found

这是我正在使用的正则表达式。它工作正常,但现在我正在尝试获取结果。

基本上,如果 name/property/etc 包含 "title",我希望它回应标题元标记的内容。

也就是说,我要的是对应的out[2],而不是out[1],当out[1]中包含"title"(不区分大小写)。

  $pattern = '
  ~<\s*meta\s

  # using lookahead to capture type to 
    (?=[^>]*?
    \b(?:name|property|http-equiv)\s*=\s*
    (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|
    ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=))
  )

  # capture content to 
  [^>]*?\bcontent\s*=\s*
    (?|"\s*([^"]*?)\s*"|\'\s*([^\']*?)\s*\'|
    ([^"\'>]*?)(?=\s*/?\s*>|\s\w+\s*=))
  [^>]*>

  ~ix';

if(preg_match_all($pattern, $link_html, $out))
{
    foreach ($out[1] as $out)
    {
        echo $out.'<br>';
    }   
}

这应该可以通过在 foreach 循环中捕获数组索引来实现,如下所示:

foreach ($out[1] as $index => $out) {
    if(stristr($out, 'title')) echo $out[2][$index].'<br>';
}

您要求使用正则表达式,但使用 HTML 解析器和 XPath 会更容易且更易读:

<?php

$html = <<< HTML
<html>
    <head>
        <meta name="author" lang="en" content="Gordon" />
        <meta name="title" lang="en" content="match this" />
        <meta property="title" lang="en" content="and this" />
        <meta http-equiv="title" lang="en" content="and also this" />
        <meta foo="title" content="but not this" />
    </head>
    <body>Use DOMDocument for HTML parsing instead</body>
</html>
HTML;

libxml_use_internal_errors(true);
$dom = new DOMDocument;
$dom->loadHTML($html);
libxml_use_internal_errors(false);

$xpath = new DOMXPath($dom);
$nodes = $xpath->evaluate(
    '//meta[
       @*[
         contains("name|property|http-equiv", name())
         and contains(., "title")
         ]
       ]/@content'
);

foreach ($nodes as $node) {
    echo $node->nodeValue, PHP_EOL;
}

输出:

match this
and this
and also this

XPath 意味着 查找任何元标记的所有内容属性,其中任何属性名称是字符串 "name|property|http-equiv" 的一部分并且包含值 "title" 在该属性中。

正如您希望看到的那样,XPath 本身读起来几乎就像是自然语言(与您使用的正则表达式相反)。