代码之家  ›  专栏  ›  技术社区  ›  ahmed

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

  •  1
  • ahmed  · 技术社区  · 15 年前

    我有一个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
    

    因为“bar”一次出现在标题标签上,一次出现在强标签上

    我知道这是一个复杂的问题,所以我问别人是否知道答案:)

    谢谢

    到目前为止我所拥有的是

            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 回复  |  直到 12 年前
        1
  •  2
  •   VolkerK    15 年前

    你可以使用 DOMDocument xpath 为此。

    <?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,而不是将bar作为单个单词,并与xpath查询匹配。因此,这个解决方案可能是不够的,也可能是不够的。

        2
  •  1
  •   Marcus Andrén    15 年前

    我不是一个PHP程序员,但一般来说,如果你能掌握一个HTMLDOM解析器,它会让你很容易理解。查找所有文本节点并搜索文本字符串。如果匹配,只需检索父节点的名称。

    如果没有DOM解析器,有两个问题需要处理。

    1. 除非使用XHTML,否则HTML不是XML。<br>是一个很好的例子,您必须对其进行硬编码。

    2. 其次,必须考虑以下标签组合“<a><b>bar<c></c></a>”。它应该导致回答“A”,而不是“B”或“C”。

    即使在找到了“bar”字符串之后,您也不能只找到下一个或上一个标记。相反,您应该将计数器设置为1,然后重新开始跟踪。当你遇到开始标记时,你会减少一个,当你遇到结束标记时,你会增加一个。当计数器降至0时,保存当前所处的标记。

    最后,还有格式错误的HTML,如“<i><b>bar</i></b>”。我真的不知道有没有一个好的方法来处理。

        3
  •  0
  •   Haim Evgi    15 年前

    我想你首先需要,

    将HTML解析为数组,

    查找执行此操作的函数: http://www.php.happycodings.com/Arrays/code35.html

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

    在这个数组中按循环搜索之后。

        4
  •  0
  •   Lucky    15 年前

    以下代码在大多数情况下都可以工作。它不会尊重HTML注释,可能会被带引号的字符串(例如 <img alt="<grin>" ... )但在像这样的病理情况下不会窒息 <i><b>foo</i>bar</b> 甚至给出了一个合理的结果。

    它没有注意到像这样的标签 <?php> 不知道空标签,比如 <br> or <input> 但是会忽略像这样的标签 </br /> . 您可以添加逻辑来忽略空标签(img、hr、br、input等)。

    搜索词被\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
    )
    
        5
  •  -1
  •   Nightfirecat peSHIr    12 年前

    嗯,这是个棘手的问题。

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