2009-08-05 115 views
1

我有一个HTML文档作为字符串如何找出HTML文档中关键字的位置?

我要搜索一个关键字的文档中,并找出在哪里它出现在文档

我的意思是在标签也看起来

在没有它出现在H1,H2或标题标签

可以说,我的文档

 $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 

因为“酒吧”出现在标题标签一次,在强烈的触杀

我知道这是一个复杂的问题一个时间,这就是为什么我问我,如果有人知道答案:)

感谢

我迄今是

 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> 
      ) 

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

感谢

回答

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查询。所以这个解决方案可能会或可能不足够。

+0

谢谢,炉排解决方案,但它并不总是工作,因为一些文件有错误我没有尝试你的代码,并将其应用于我的文档之一,并且DOM解析器生成11解析错误,谢谢 – ahmed 2009-08-05 08:05:01

-1

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

为什么不在字符串中搜索关键字,请记住找到它的位置,然后向后遍历字符串,直到看到第一个“<”,将它写入您的数组,直到看到“ >”。

1

我不是一个PHP程序员,但通常如果你能得到一个HTML DOM解析器,它会让它变得容易。找到所有文本节点并搜索文本字符串。当你有一个匹配时,只需检索父节点的名称。

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

  1. 除非您使用的是xhtml,否则html不是xml。 < br>是一个很好的例子,你将不得不硬编码。

  2. 其次,下面的标记组合将必须被认为是 “<一个> < B>巴< C> </C> </A>”。它应该导致答案为“a”,而不是“b”或“c”。

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

最后,还有格式不正确的html,例如“< i> < b> bar </i> </b>”。我真的不知道是否有一个好的方法来解决这个问题。

+0

谢谢你,是的,它是有用的,如果我可以使用DOM解析器,我没有想到这一点!它看起来是一个格栅解决方案,但我不确定在PHP中是否有DOM解析器! – ahmed 2009-08-05 07:53:34

+0

是的,有,http://php.net/dom – VolkerK 2009-08-05 07:56:00

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 
) 
相关问题