PHP RegExp для вложенных тегов Div

Мне нужно регулярное выражение, которое я могу использовать с preg_match_all () PHP, чтобы соответствовать содержимому внутри div-тегов. Дивы выглядят так:

<div id="t1">Content</div> 

Я до сих пор сталкивался с этим регулярным выражением, которое соответствует всем div с id = "t [number]"

 /<div id="t(\\d)">(.*?)<\\/div>/ 

Проблема заключается в том, что содержимое содержит больше divs, вложенных divs, таких как:

 <div id="t1">Content <div>more stuff</div></div> 

Любые идеи о том, как заставить мое регулярное выражение работать с вложенными тегами?

благодаря

Вместо этого попробуйте парсер:

 require_once "simple_html_dom.php"; $text = 'foo <div id="t1">Content <div>more stuff</div></div> bar <div>even more</div> baz <div id="t2">yes</div>'; $html = str_get_html($text); foreach($html->find('div') as $e) { if(isset($e->attr['id']) && preg_match('/^t\d++/', $e->attr['id'])) { echo $e->outertext . "\n"; } } 

Вывод:

 <div id="t1">Content <div>more stuff</div></div> <div id="t2">yes</div> 

Загрузите синтаксический анализатор здесь: http://simplehtmldom.sourceforge.net/

Изменить: больше для моего собственного развлечения я попытался сделать это в regex. Вот что я придумал:

 $text = 'foo <div id="t1">Content <div>more stuff</div></div> bar <div>even more</div> baz <div id="t2">yes <div>aaa<div>bbb<div>ccc</div>bbb</div>aaa</div> </div>'; if(preg_match_all('#<div\s+id="t\d+">[^<>]*(<div[^>]*>(?:[^<>]*|(?1))*</div>)[^<>]*</div>#si', $text, $matches)) { print_r($matches[0]); } 

Вывод:

 Array ( [0] => <div id="t1">Content <div>more stuff</div></div> [1] => <div id="t2">yes <div>aaa<div>bbb<div>ccc</div>bbb</div>aaa</div> </div> ) 

И небольшое объяснение:

 <div\s+id="t\d+"> # match an opening 'div' with an id that starts with 't' and some digits [^<>]* # match zero or more chars other than '<' and '>' ( # open group 1 <div[^>]*> # match an opening 'div' (?: # open a non-matching group [^<>]* # match zero or more chars other than '<' and '>' | # OR (?1) # recursively match what is defined by group 1 )* # close the non-matching group and repeat it zero or more times </div> # match a closing 'div' ) # close group 1 [^<>]* # match zero or more chars other than '<' and '>' </div> # match a closing 'div' 

Теперь, возможно, вы понимаете, почему люди пытаются убедить вас в том, что вы не используете регулярное выражение для этого. Как уже отмечалось, это не поможет, если html неправильно сформирован: регулярное выражение сделает больше бесполезности вывода, чем синтаксический анализатор html, уверяю вас. Кроме того, регулярное выражение, вероятно, сделает ваши глаза кровоточащими, и ваши коллеги (или люди, которые будут поддерживать ваше программное обеспечение) могут найти вас, увидев, что вы сделали. 🙂

Лучше всего сначала очистить свой вход (используя TIDY или аналогичный), а затем использовать парсер, чтобы получить нужную вам информацию.

Если вы верите этому парню, есть хотя бы одно регулярное выражение, которое делает трюк, и он говорит, что это быстрее, чем домашние методы … Я согласен с ним.

http://www.php.net/manual/fr/regexp.reference.recursive.php#95568

$ pattern = "/ <([\ w] +) ([^>] ?) (([\ s] />) | (> (([^ <] ? | <! -. ? -> ) | (? R)) ) </ \ 1 [\ s] >)) / xsm ";

я думаю, будет лучше использовать некоторые DOM-инструменты

Как я недавно узнал, регулярное выражение не может этого сделать.

Соответствие парному тегу с регулярным выражением

Я закончил использовать xpath, и он работает как шарм