如何确定HTML文档中关键字的位置?

时间:2009-08-05 07:09:39

标签: php html

我有一个HTML文档作为字符串

我想在此文档中搜索关键字,并找出它在文档中的显示位置

我的意思是它出现在哪个标签上

是否出现在H1,H2或TITLE标签

我要说的是我的文件

        $string = "<html>
                   <head> 
                   <title>bar , this is an example</title> 
                   </head> 
                   <body> 
                   <h1>latest news</h1>
                   foo <strong>bar</strong> 
                   </body>
                   </html>";


                   $arr = find_term("bar",$string);
                   print_r($arr);

我希望结果像这样

                   [0]=> title
                   [1]=> strong

因为“bar”在TITLE标签中出现一次,在STRONG标签中出现一次

我知道这是一个复杂的问题,这就是为什么我在问是否有人知道答案:)

感谢

到目前为止我所拥有的是

        function find_term($term,$string){
               $arr = explode($term, $string);
               return $arr;
        }
        $arr = find_term("bar",$string);
        print_r($arr);

现在我们有一个值

的数组
             Array
             (
             [0] => <html>
               <head>
               <title>

             [1] =>  , this is an example</title>
               </head>
               <body>
               <h1>latest news</h1>
               foo <strong>

             [2] => </strong>
               </body>
               </html>
             )

你可以看到数组中每个元素的最后一个标记是包含“bar”的标记 但现在的问题是如何知道每个元素中出现的最后一个标记?

由于

5 个答案:

答案 0 :(得分:2)

您可以使用DOMDocumentxpath

<?php
$doc = new DOMDocument;
$doc->loadhtml('<html>
  <head> 
    <title>bar , this is an example</title> 
  </head> 
  <body> 
    <h1>latest news</h1>
    foo <strong>bar</strong> 
    <i>foobar</i>
   </body>
</html>');
$xpath = new DOMXPath($doc);
foreach($xpath->query('//*[contains(child::text(),"bar")]') as $e) {
  echo $e->tagName, "\n";
}

打印

title
strong
i

注意i元素。它包含foobar,而不是单词作为单词并匹配xpath查询。所以这个解决方案可能也可能不够。

答案 1 :(得分:1)

我不是一个php程序员,但通常如果你能掌握一个html dom解析器,它会让它变得简单。查找所有文本节点并在其中搜索文本字符串。如果匹配,只需检索父节点的名称。

没有dom解析器,有两个问题需要处理。

  1. 除非您使用的是xhtml,否则html不是xml。 &LT峰; br&GT;是一个很好的例子,你必须硬编码。

  2. 其次,以下标签组合必须被视为“&lt; a&gt;&lt; b&gt; bar&lt; c&gt;&lt; / c&gt;&lt; / a&gt;”。它应该得到答案“a”,而不是“b”或“c”。

  3. 即使找到了“bar”字符串,也不能只找到下一个或上一个标记。相反,您应该将计数器设置为1并开始追溯。当您遇到开始标记时,减少1,当您遇到结束标记时,您会增加1。当计数器降至0时,保存当前所在的标签。

    最后,还存在格式错误的html,例如“&lt; i&gt;&lt; b&gt; bar&lt; / i&gt;&lt; / b&gt;”。我真的不知道是否有一个很好的方法来解决这个问题。

答案 2 :(得分:0)

我想你首先需要,

将html解析为数组,

找到类似的功能:http://www.php.happycodings.com/Arrays/code35.html

或类似:http://www.phpclasses.org/browse/package/5139.html

之后循环搜索此数组。

答案 3 :(得分:0)

以下代码大部分时间都可以使用。它不会尊重HTML注释,可能会被引用的字符串混淆(例如<img alt="<grin>" ...),但不会对像<i><b>foo</i>bar</b>这样的病态案例感到困惑,甚至会给出合理的结果。

它没有注意到<?php>等标记,也不知道<br> or <input>之类的空标记,但会忽略</br />之类的标记。您可以添加逻辑来忽略空标记(img,hr,br,输入等)。

搜索字被\ b(字边界)包围,因此foobar不匹配。

$html   = "<html>
               <head>
               <title>bar , this is an example</title>
               </head>
               <body class=3>
               <h1>latest news</h1>
               foo <strong>bar</strong> <br />bar
               <i>foobar</i>
               </body>
               </html>";
$search = 'bar';

preg_match_all('/(\<(\/?)(\w+).*?(\/?)\>)|(\b'.$search.'\b)/i', $html, $matches, PREG_SET_ORDER);

$tags = array();
$found = array();
foreach ($matches as $m) {
    if ($m[2] == '/') {
        $n = array_search($m[3], $tags);
        if ($n !== false)
            array_splice($tags, $n, 1);
    }
    else if ($m[3] and !$m[4]) {
        array_unshift($tags, $m[3]);
    }
    else if ($m[5]){
        $found[] = $tags[0];
    }
}
print_r($found);

输出(<br />标签后面的额外栏)

Array
(
    [0] => title
    [1] => strong
    [2] => body
)

答案 4 :(得分:-1)

嗯,这是一个棘手的问题。

为什么不在字符串中搜索关键字,记住找到它的位置,然后向后浏览字符串直到看到第一个“&lt;”,将其写入数组,直到看到“ &gt;”中