в чем разница между двумя регулярными выражениями (отрицательный взгляд)?

я мог сопоставить содержимое между тегами tr с этим регулярным выражением:

<tr\s+class='test'>((?!</tr>).)*</tr>

но если я помещу звездчатые квантификаторы в круглые скобки рядом с метасимволами точки, они будут соответствовать только всему шаблону с пустой группой захвата.

$string = "<tr class='test'>
<td>test1</td>
</tr>
 <div class='ignored' >text text</div>
 <tr class='test'>
 <td>test2</td>
 </tr>";


preg_match_all("|<tr\s+class='test'>((?!</tr>).*)</tr>|si",$string,$matches);

print_r($matches);

Я знаю, что такое поиск, но не совсем уверен, в чем именно заключается разница. надеюсь, что кто-то сможет пролить свет на это. Спасибо!


person benson    schedule 28.12.2013    source источник
comment
О, разбор HTML с помощью регулярного выражения? Прошло некоторое время с тех пор, как я видел вопрос в этом аспекте :-) Надеюсь, вы знаете об этом: stackoverflow.com/questions/1732348/ Удачи, кстати, с поиском правильного выражения .   -  person Darin Dimitrov    schedule 28.12.2013
comment
Спасибо за ссылку. Я попробовал simple_html_dom, но не смог решить мою проблему. какие альтернативы вы порекомендуете, если я хочу извлечь содержимое из тегов tr с именем класса certian? В любом случае, я изучаю регулярное выражение и хочу понять, как оно работает.   -  person benson    schedule 28.12.2013
comment
Извините, я не разработчик PHP и не могу предложить хороших фреймворков для синтаксического анализа HTML. Что я могу сказать с уверенностью, так это то, что если вы хотите изучить регулярное выражение, синтаксический анализ HTML - это НАИЛУЧШИЙ пример, который вы могли бы выбрать для изучения.   -  person Darin Dimitrov    schedule 28.12.2013


Ответы (1)


((?!</tr>).)*

Повторение применяется к ((?!</tr>).), и есть один . и один просмотр вперед. Следовательно, это будет проверять каждый . (при каждом повторении) и удостоверяться, что за ними не следует </tr>.

((?!</tr>).*)

На самом деле это замаскированный (?!</tr>).*. Есть один просмотр вперед и один .*. Предварительный просмотр будет проверять только первые ., но не остальные, поэтому все будет сопоставлено, если только точки, расположенные непосредственно после предварительного просмотра, не совпадают с </tr>.

person Jerry    schedule 28.12.2013