Я изучаю RegEx и сканирование сайта, и у меня возникает следующий вопрос, который, если он отвечает, должен значительно ускорить процесс обучения.
Я получил элемент формы с веб-сайта в формате htmlencoded. То есть, у меня есть строка $ content со всеми тэгами без изменений:
$content = "<form name="sth" action=""> <select name="city"> <option value="one">One town</option> <option value="two">Another town</option> <option value="three">Yet Another town</option> ... </select> </form>
Я хотел бы получить все варианты на сайте, таким образом:
array("One Town" => "one", "Another Town" => "two", "Yet Another Town" => "three" ...);
Теперь я знаю, что это легко можно сделать, манипулируя строкой, разрезая ее нарезать ее, искать подстроки внутри каждой строки и т. Д., Пока у меня не будет всего, что мне нужно. Но я уверен, что должен быть более простой способ сделать это с помощью регулярного выражения, которое должно извлекать все результаты из заданной строки мгновенно. Может ли кто-нибудь помочь мне найти ярлык для этого? Я искал лучшие веб-сайты регулярных выражений, но безрезультатно.
Большое спасибо
См. « Лучшие методы для анализа HTML» . Найдите решение DOM ниже:
$dom = new DOMDocument; $dom->loadHTMLFile('http://example.com'); $options = array(); foreach($dom->getElementsByTagName('option') as $option) { $options[$option->nodeValue] = $option->getAttribute('value'); }
Это также можно сделать с помощью Regex , но я не считаю целесообразным написать надежный HTML-парсер с Regex, когда есть много собственных и сторонних парсеров, которые легко доступны для PHP.
Я думаю, что было бы проще использовать DomXPath, а не использовать регулярные выражения для этого. Вы можете попробовать что-то вроде этого (не тестировались, поэтому могут потребоваться некоторые настройки) …
<?php $content = '<form name="sth" action=""> <select name="city"> <option value="one">One town</option> <option value="two">Another town</option> <option value="three">Yet Another town</option> </select> </form>'; $doc = new DOMDocument; $doc->loadhtml($content); $xpath = new DOMXPath($doc); $options = $xpath->evaluate("/html/body//option"); for ($i = 0; $i < $options->length; $i++) { $option = $options->item($i); $values[] = $option->getAttribute('value'); } var_dump($values); ?>
<?php $content = '<form name="sth" action=""> <select name="city"> <option value="one">One town</option> <option value="two">Another town</option> <option value="three">Yet Another town</option> </select> </form>'; preg_match_all('@<option value=\"(.*)\">(.*)</option>@', $content,$matches); echo "<pre>"; print_r($matches); ?>
Теперь $ matches содержит массивы, которые вы ищете, и вы можете легко их обработать до результата.
Использование SimpleXML:
libxml_use_internal_errors(true); $load = simplexml_load_string($content); foreach ($load->xpath('//select/option') as $path) var_dump((string)$path[0]);
Если это действительно когерентный HTML, то простое регулярное выражение будет делать:
preg_match('/<option\s+value="([^">]+)">([^<]+)/i', ...
Однако часто проще и надежнее использовать phpQuery или QueryPath.
$options = qp($html)->find("select[name=city]")->find("option"); foreach ($options as $o) { $result[ $o->attr("value") ] = $o->text(); }