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

使用php从h1标记获取所有值,php,html,find,Php,Html,Find,我希望接收一个数组,该数组包含来自文本的所有h1标记值 例如,如果这是给定的输入字符串: <h1>hello</h1> <p>random text</p> <h1>title number two!</h1> 我已经知道如何获取字符串的第一个h1值,但是我需要给定字符串中所有h1标记的所有值 我目前正在使用它来接收第一个标签: function getTextBetweenTags($string, $tagname)

我希望接收一个数组,该数组包含来自文本的所有h1标记值

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

<h1>hello</h1>
<p>random text</p>
<h1>title number two!</h1>
我已经知道如何获取字符串的第一个h1值,但是我需要给定字符串中所有h1标记的所有值

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

function getTextBetweenTags($string, $tagname) 
 {
  $pattern = "/<$tagname ?.*>(.*)<\/$tagname>/";
  preg_match($pattern, $string, $matches);
  return $matches[1];
 }
函数getTextBetweenTags($string,$tagname) { $pattern=“/(.*)/”; 预匹配($pattern,$string,$matches); 返回$matches[1]; } 我将要解析的字符串传递给它,并作为$tagname输入“h1”。 虽然不是我自己写的,我一直在尝试编辑代码来做我想做的事情,但是没有什么真正起作用

我希望有人能帮我

提前感谢。

您可以使用:

函数getTextBetweenH1($string) { $pattern=“/(**?/”; preg_match_all($pattern,$string,$matches); 返回($matches[1]); }
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();
    }
}
$html=read()!=(错误){
if($reader->name=='h1'&&$reader->nodeType===XMLReader::ELEMENT){
echo$reader->readString();
}
}

至少您应该使用preg\u match\u all。看看哦,我不知道你能做到!simplehtmldom是否比DOMDocument快,或者只是在DOMDocument不存在的情况下(尽管默认情况下启用了它)?@Wrikken它是用户代码,所以它怀疑它是否快。不知道为什么人们对它如此着迷(必须是名称上的简单),特别是因为还有,或者是其他选择。@kgb DOM可以加载无效的HTML,如果您使用loadHTML加载它。唯一不起作用的是getElementById,这完全是由于HTML4.0DTD的回退。您仍然可以通过XPath按ID查询节点。此外,您根本不必使用@来抑制错误。您可以使用libxml\u use\u internal\u errors并通过自定义错误处理程序处理任何错误。SimpleHTMLDom并不更适合HTML。它甚至不使用libxml,而是使用字符串函数解析HTML。-1感谢没有使用内置的c扩展来做完全相同的事情(说真的,如果PHP核心中内置了完全相同的事情,为什么要在PHP中做这些事情。。。改为使用
DomDocument
…谢谢,不过我仍然在使用DOM方法。仍然感谢您花时间回答:)@Pieter-yup,如果Wrikken还没有提供DOM解决方案的话,我已经自己提供了。在这里使用正则表达式非常好。他没有解析HTML。他在
之间进行匹配,这本来就是有规律的。将正则语言与正则表达式匹配是非常好的。抛开大家都在大肆宣传的“如果涉及HTML,OMG正则表达式就不能用于任何事情”这种愚蠢的废话。这并不是说他试图匹配所有的HTML,只是语言的一个很小的子集,恰好是规则的。@Daniel如果
有属性怎么办?如果标题包含元素子元素怎么办?@Gordon:属性问题可以使用以下正则表达式解决:
)*>(.*)i
(我认为它仍然描述一种常规语言,因此可以使用有限状态机表示)。子元素的问题不存在,因为在另一个
中无论如何都不可能有
。编辑:正则表达式是为一个带引号的PHP字符串编写的。@Daniel您必须承认这是完全不可读的:)此外,h1中可能有内联元素。跨度呢?强者?特快专递?这个页面的h1内部有一个链接。Regex没有TextNodes的概念。它只知道字符串。即使H1元素中有内联元素,这个正则表达式仍然可以工作。。。嗯,它是不是不可读也没关系,因为它是一个集而忘的函数。
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;
    }
}
function getTextBetweenTags($string, $tagname){
    $d = new DOMDocument();
    $d->loadHTML($string);
    $return = array();
    foreach($d->getElementsByTagName($tagname) as $item){
        $return[] = $item->textContent;
    }
    return $return;
}
 function getTextBetweenH1($string)
 {
    $pattern = "/<h1>(.*?)<\/h1>/";
    preg_match_all($pattern, $string, $matches);
    return ($matches[1]);
 }
$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();
    }
}