PHP RegEx Группировка нескольких совпадений

Я просто пробую свои силы в создании своего самого первого регулярного выражения. Я хочу иметь возможность сопоставлять псевдо HTML-элемент и извлекать полезную информацию, такую ​​как имя тега, атрибуты и т. Д.:

$string = '<testtag alpha="value" beta="xyz" gamma="abc"  >';

if (preg_match('/<(\w+?)(\s\w+?\s*=\s*".*?")+\s*>/', $string, $matches)) {
    print_r($matches);
}

За исключением того, что я получаю:

Array ( [0] =>  [1] => testtag [2] => gamma="abc" ) 

Кто-нибудь знает, как я могу получить другие атрибуты? Что мне не хватает?

3 ответа

Попробуйте это регулярное выражение:

/<(\w+)((?:\s+\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]*))*)\s*>/

Но вы действительно не должны использовать регулярные выражения для языка без контекста, такого как HTML. Вместо этого используйте настоящий парсер.

Как уже было сказано, не используйте RegEx для анализа HTML-документов.

Попробуйте вместо этого этот синтаксический анализатор PHP: http://simplehtmldom.sourceforge.net/

Ваша вторая группа захвата соответствует атрибутам по одному, каждый раз перезаписывая предыдущий. Если бы вы использовали регулярные выражения.NET, вы могли бы использовать массив Captures для извлечения отдельных захватов, но я не знаю ни одного другого варианта регулярного выражения, имеющего эту функцию. Обычно вам нужно сделать что-то вроде захвата всех атрибутов в одной группе, а затем использовать другое регулярное выражение для захваченного текста, чтобы выделить отдельные атрибуты.

Вот почему люди склонны либо любить регулярные выражения, либо ненавидеть их (или обоих). Вы можете делать с ними действительно удивительные вещи, но вы также продолжаете сталкиваться с такими простыми задачами, как эта, которые смехотворно сложны, если не невозможны.

Другие вопросы по тегам