preg_match_all для анализа xml-подобной строки атрибута - PullRequest
1 голос
/ 28 марта 2010

У меня есть строка примерно так:

option_alpha="value" option_beta="some other value" option_gamma="X" ...etc.

Я использую это, чтобы разобрать их в пары имя и значение:

preg_match_all("/([a-z0-9_]+)\s*=\s*[\"\'](.+?)[\"\']/is", $var_string, $matches)

, которая прекрасно работает, если не встречаетпустое значение атрибута:

option_alpha="value" option_beta="" option_gamma="X"

Что я сделал неправильно в своем регулярном выражении?

Ответы [ 3 ]

3 голосов
/ 28 марта 2010
[\"\'](.+?)[\"\']

должно быть

[\"\'](.*?)[\"\']

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

0 голосов
/ 12 апреля 2010

Другие ответы здесь верны в том, что вам нужно изменить середину выражения, но я бы изменил его на [^ \ "\ '] *, что означает" любой символ, который не является ", 0 или более раз . Это гарантирует, что жадность не соответствует больше, чем предполагалось, и допускает пустое "".

ваше выражение становится
"/ ([А-z0-9 _] +) \ s * = \ с * [\" \ '] [^ \ "\'] * [\ "\ "] / есть"

обратите внимание, что вы можете изменить [a-z0-9_] на [\ w_], что также для символов верхнего регистра.

0 голосов
/ 28 марта 2010

Я думаю, вы хотите изменить самую середину вашего выражения с (.+?) на (.*?). Это делает его не жадным совпадением для любого символа (включая символы), а не жадным совпадением хотя бы для одного символа.

preg_match_all("/([a-z0-9_]+)\s*=\s*[\"\'](.*?)[\"\']/is",$var_string,$matches);
...