使用php从h1标签获取所有值

Pie*_*888 14 html php find

我想收到一个包含文本中所有h1标记值的数组

例如,如果这个给定的输入字符串:

<h1>hello</h1>
<p>random text</p>
<h1>title number two!</h1>
Run Code Online (Sandbox Code Playgroud)

我需要收到一个包含这个的数组:

titles[0] = 'hello',
titles[1] = 'title number two!'
Run Code Online (Sandbox Code Playgroud)

我已经弄清楚如何获取字符串的第一个h1值,但我需要给定字符串中所有h1标签的所有值.

我目前正在使用它来接收第一个标签:

function getTextBetweenTags($string, $tagname) 
 {
  $pattern = "/<$tagname ?.*>(.*)<\/$tagname>/";
  preg_match($pattern, $string, $matches);
  return $matches[1];
 }
Run Code Online (Sandbox Code Playgroud)

我传递了我想要解析的字符串,并将其作为$ tagname放入"h1".我自己没有写它,我一直在尝试编辑代码来做我想要的但没有真正有效.

我希望有人可以帮助我.

提前致谢.

Ser*_*min 32

你可以使用simplehtmldom:

function getTextBetweenTags($string, $tagname) {
    // Create DOM from string
    $html = str_get_html($string);

    $titles = array();
    // Find all tags 
    foreach($html->find($tagname) as $element) {
        $titles[] = $element->plaintext;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • simplehtmldom是否比DOMDocument更快或仅适用于DOMDocument不存在的情况(尽管默认启用)? (2认同)
  • 如果使用loadHTML加载,@ kgb DOM可以加载无效的HTML.唯一不起作用的是getElementById,这完全是由于回退到HTML4.0 DTD.您仍然可以通过XPath通过ID查询节点.此外,您根本不必使用@来抑制错误.您可以使用libxml_use_internal_errors并通过自定义错误处理程序处理任何错误.SimpleHTMLDom不适合HTML.它甚至不使用libxml,但使用String函数解析HTML. (2认同)
  • -1,因为没有使用内置的c扩展来做同样的事情(严重的是,为什么在PHP中,如果在PHP核心中内置完全相同的东西?)...使用`DomDocument`代替... (2认同)

Wri*_*ken 22

function getTextBetweenTags($string, $tagname){
    $d = new DOMDocument();
    $d->loadHTML($string);
    $return = array();
    foreach($d->getElementsByTagName($tagname) as $item){
        $return[] = $item->textContent;
    }
    return $return;
}
Run Code Online (Sandbox Code Playgroud)


Gor*_*don 8

DOM的替代品.在内存出现问题时使用.

$html = <<< HTML
<html>
<h1>hello<span>world</span></h1>
<p>random text</p>
<h1>title number two!</h1>
</html>
HTML;

$reader = new XMLReader;
$reader->xml($html);
while($reader->read() !== FALSE) {
    if($reader->name === 'h1' && $reader->nodeType === XMLReader::ELEMENT) {
        echo $reader->readString();
    }
}
Run Code Online (Sandbox Code Playgroud)


Ahm*_*man 7

 function getTextBetweenH1($string)
 {
    $pattern = "/<h1>(.*?)<\/h1>/";
    preg_match_all($pattern, $string, $matches);
    return ($matches[1]);
 }
Run Code Online (Sandbox Code Playgroud)

  • 在这里使用正则表达式非常好。他不是在解析 HTML。他正在匹配 `&lt;h1&gt;` 和 `&lt;/h1&gt;` 之间的东西,这本质上是规则的。将正则语言与正则表达式相匹配非常好。放弃每个人似乎都在大肆宣传的无意识的“如果涉及 HTML,则 OMG 正则表达式不能用于任何事情”的废话。这并不是说他试图匹配所有的 HTML,只是碰巧是常规语言的一个很小的子集。 (12认同)
  • @Daniel 如果“&lt;h1&gt;”有属性怎么办?如果标题包含子元素怎么办? (2认同)
  • @Gordon:属性问题可以用这个正则表达式解决:`#&lt;h1(?:"(?:[^\\\"]|\\\.)*"|\'(?:[^\\\ \\']|\\\.)*\'|[^\'"&gt;])*&gt;(.*?)&lt;/h1&gt;#i`(我相信它仍然描述了一种常规语言,因此可以表示使用有限状态机)。子元素的问题不存在,因为无论如何都不能在另一个 `&lt;h1&gt;` 中存在 `&lt;h1&gt;`。编辑:正则表达式是为单引号 PHP 字符串编写的。 (2认同)
  • @Daniel 你必须承认这是完全不可读的 :) 此外,h1 中可以有内联元素。跨度呢?强者?ems?这个页面的 h1 里面有一个链接。Regex 没有 TextNodes 的概念。它只知道字符串。 (2认同)
  • 这个正则表达式仍然有效,即使 H1 元素中有内联元素......恕我直言,它是否不可读也没关系,因为它是一个设置和忘记功能。 (2认同)