Php 正则表达式:解析多个带引号的名称/值对
在PHP5.6/7.0中工作 我在几个regex网站上尝试了几个问题和几个小时的regex,但找不到任何我需要的东西。我有这样一个字符串:Php 正则表达式:解析多个带引号的名称/值对,php,regex,pcre,Php,Regex,Pcre,在PHP5.6/7.0中工作 我在几个regex网站上尝试了几个问题和几个小时的regex,但找不到任何我需要的东西。我有这样一个字符串: At vero eos et accusamus et iusto odio dignissimos ducimus <!-- @@include default="/admin/creditapp/templates/longform/" try="/wTemplates/forms/templates/" file="credit_row_1.t
At vero eos et accusamus et iusto odio dignissimos ducimus
<!-- @@include default="/admin/creditapp/templates/longform/" try="/wTemplates/forms/templates/" file="credit_row_1.txt" -->
qui blanditiis praesentium voluptatum deleniti atque corrupti
<!-- @@include default="/admin/creditapp/templates/longform/" try="/wTemplates/forms/templates/" file="credit_row_2.txt" -->
quos dolores et quas excepturi sint
vero eos et accusamus et iusto odio dignessimos ducimus
白兰地病导致腐败
除圣城外的其他地方
我正在从令牌中查找以下匹配项:
<!-- @@include ...the whole thing... -->
default
/admin/creditapp/templates/longform
try
/wtemplates/forms/templates
file
credit_row_1.txt
违约
/管理员/creditapp/templates/longform
尝试
/wtemplates/表单/模板
文件
credit_row_1.txt
每次发现整个群体时,自然会重复。我可以循环文件并完成它,所以一次只需一个实例就可以了。我唯一能想到的表达方式就是:
<!-- @@include (?:(try|default|file)=\"(.+?)\"?)(?:\s*)(?:(try|default|file)=\"(.+?)\"?)(?:\s*)(?:(try|default|file)=\"(.+?)\"?)(?:\s*)-->
这是巨大的,并且不考虑其他可能性,比如,我不知道,“(try | foo | bar | default)”或其他什么,或者省略“try”或“default”,例如“(foo | bar | file)。”
在模板中
<!-- @@include -->
是恒定的。内部可以是2到n个名称=值对。我试过:
(<!-- @@include (?:(try|default|file)=\"(.+?)\" ?){1,3}-->)
()
但它只返回lastname=找到的值。我想我已经很接近了,但我无法计算出来。PCRE无法存储重复捕获组的不同内容。重复组时,上一个内容将被当前内容覆盖,以此类推。
一种解决方法是使用
preg\u match\u all
并使用\G
锚,该锚与上一次匹配后的下一个位置相匹配(默认情况下,它也与字符串的开头相匹配)
要获得更灵活且能够处理未知密钥的功能,您可以使用两个
preg\u match\u all
:
$result = [];
if ( preg_match_all('~<!-- @@include\s+\K\w+=".*?"(?:\s+\w+=".*?")*~', $str, $matches) ) {
foreach ($matches[0] as $params) {
if ( preg_match_all('~(\w+)="(.*?)"~', $params, $keyvals) )
$result[] = array_combine($keyvals[1], $keyvals[2]);
}
}
print_r($result);
$result=[];
如果(预匹配全部('~
$result = [];
if ( preg_match_all('~(?:\G(?!\A)|<!-- (@)@include)\s+(try|default|file)="(.*?)"~', $str, $matches, PREG_SET_ORDER) ) {
foreach ($matches as $m) {
if ( !empty($m[1]) ) { // test which branch succeeds
if ( isset($temp) )
$result[] = $temp;
$temp=[];
}
$temp[$m[2]] = $m[3];
}
}
if ( isset($temp) )
$result[] = $temp;
$result = [];
if ( preg_match_all('~<!-- @@include\s+\K\w+=".*?"(?:\s+\w+=".*?")*~', $str, $matches) ) {
foreach ($matches[0] as $params) {
if ( preg_match_all('~(\w+)="(.*?)"~', $params, $keyvals) )
$result[] = array_combine($keyvals[1], $keyvals[2]);
}
}
print_r($result);