Как выяснить расположение ключевого слова в документе HTML? - PullRequest
1 голос
/ 05 августа 2009

У меня есть 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 ]

2 голосов
/ 05 августа 2009

Для этого вы можете использовать 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. Таким образом, это решение может или не может быть достаточно.

1 голос
/ 05 августа 2009

Я не программист php, но, как правило, если вы можете получить html dom-парсер, это будет легко. Найдите все текстовые узлы и найдите в них текстовую строку. Если у вас есть совпадение, просто получите имя родительского узла.

Без синтаксического анализатора dom есть две проблемы, с которыми приходится иметь дело.

  1. Если вы не используете xhtml, html не является xml.
    является хорошим примером того, что вам придется жестко закодировать.

  2. Во-вторых, следует учитывать следующую комбинацию тегов " bar ". Это должно привести к ответу "a", а не "b" или "c".

Даже после нахождения строки «bar» вы не можете просто найти следующий или предыдущий тег. Вместо этого вы должны установить счетчик на 1 и начать отслеживание. Когда вы встречаете начальный тег, вы уменьшаетесь на единицу, а когда вы сталкиваетесь с конечным тегом, вы увеличиваете его на единицу. Когда счетчик упадет до 0, сохраните тег, на котором вы сейчас находитесь.

Наконец, есть также искаженный html, такой как " bar ". Я действительно не знаю, есть ли хороший способ справиться с этим.

0 голосов
/ 05 августа 2009

Следующий код будет работать большую часть времени. Он не учитывает комментарии 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
)
0 голосов
/ 05 августа 2009

Хм, это сложный вопрос.

Почему бы вам не выполнить поиск в строке по ключевому слову, запомнить позицию, в которой вы его нашли, а затем пройти строку назад, пока не увидите первое «<», записать это в свой массив, пока не увидите «> ».

0 голосов
/ 05 августа 2009

Я думаю, тебе сначала нужно,

разбирать HTML в массив,

функция поиска, которая делает это следующим образом: http://www.php.happycodings.com/Arrays/code35.html

или класс как: http://www.phpclasses.org/browse/package/5139.html

после этого поиска в этом массиве по циклу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...