【问题标题】:preg_match_all to parse an xml-like attribute stringpreg_match_all 解析类似 xml 的属性字符串
【发布时间】:2010-03-28 18:27:54
【问题描述】:
我有一个这样的字符串:
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"
我的正则表达式做错了什么?
【问题讨论】:
标签:
php
regex
attributes
preg-match
preg-match-all
【解决方案1】:
[\"\'](.+?)[\"\']
应该是
[\"\'](.*?)[\"\']
* 而不是+。第一个意味着前一个表达式的任何出现都可以为零(因此可以省略,这就是您所需要的)。后者的意思是,必须至少有一个。
【解决方案2】:
我认为您想将表达式的中间部分从 (.+?) 更改为 (.*?)。这使它成为对任何字符(包括无字符)的非贪婪匹配,而不是对至少一个字符的非贪婪匹配。
preg_match_all("/([a-z0-9_]+)\s*=\s*[\"\'](.*?)[\"\']/is",$var_string,$matches);
【解决方案3】:
这里的其他答案是正确的,因为您需要更改表达式的中间部分,但我会将其更改为 [^\"\']* ,这意味着“任何不是 a 的字符”,0 次或更多次. 这样可以确保贪婪不会比预期的匹配更多,并允许空的“”。
你的表情变成了
"/([a-z0-9_]+)\s*=\s*[\"\'][^\"\']*[\"\']/is"
请注意,您可以将 [a-z0-9_] 更改为 [\w_],这也适用于大写字符。