我正在尝试将某些xml标记与正则表达式匹配 这是我的PHP代码
$pattern = '#<xt:tag_name *(type\="(.+?)")? *(detail\="(.+?)")? ?/>#ui';
$str = '<xt:tag_name type="1" detail="2" />';
preg_replace($pattern,"type: $1, detail: $4",$str);
preg_match($pattern,$str,$m);
print_r($m);
我得到了预期的结果
Array
(
[0] => <xt:tag_name type="1" detail="2" />
[1] => type="1"
[2] => 1
[3] => detail="2"
[4] => 2
)
但是当我改变属性的顺序时
<xt:tag_name detail="2" type="1" />
匹配失败
答案 0 :(得分:3)
此正则表达式将捕获属性type
和detail
,无论属性顺序如何,只要它们位于xt:tag_name
标记内。
<xt:tag_name\b(?=\s)(?=(?:(?!\>).)*\s\btype=(["'])((?:(?!\1).)*)\1)(?=(?:(?!\>).)*\s\bdetail=(["'])((?:(?!\3).)*)\3)(?:(?!\>).)*\>
<xt:tag_name\b
验证标记名称(?=\s)
确保标记名称后面有空格(?=
预测type
的1。通过使用前瞻,您可以按任何顺序捕获属性。
(?:(?!\>).)*
一次移动标记一个字符并阻止正则表达式引擎退出此标记,直至到达\s\btype=
属性type
(["'])
捕获公开引用,稍后将用于匹配正确的关闭标记((?:(?!\1).)*)
捕获引号内的所有字符,但不包括相同类型的封装引用\1
匹配关闭报价)
关闭type
(?=(?:(?!\>).)*\s\bdetail=(["'])((?:(?!\3).)*)\3)
对名为detail
的属性执行与type
(?:(?!\>).)*
匹配所有字符,直到\>
标记的结尾组0将具有从打开到关闭括号的整个标记
type
值打开引号,这样正则表达式可以正确匹配关闭引用type
detail
值打开引号,这样正则表达式可以正确匹配关闭引用detail
输入字符串
<xt:tag_name UselessAttribute="some dumb string" type="1" detail="2" /><xt:tag_name detail="Things 'Punk' Loves" MoreUselessAttributes="1231" type="kittens" />
代码
<?php
$sourcestring="your source string";
preg_match_all('/<xt:tag_name\b(?=\s)(?=(?:(?!\>).)*\s\btype=(["\'])((?:(?!\1).)*)\1)(?=(?:(?!\>).)*\s\bdetail=(["\'])((?:(?!\3).)*)\3)(?:(?!\>).)*\>/ims',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
匹配
$matches Array:
(
[0] => Array
(
[0] => <xt:tag_name UselessAttribute="some dumb string" type="1" detail="2" />
[1] => <xt:tag_name detail="Things 'Punk' Loves" MoreUselessAttributes="1231" type="kittens" />
)
[1] => Array
(
[0] => "
[1] => "
)
[2] => Array
(
[0] => 1
[1] => kittens
)
[3] => Array
(
[0] => "
[1] => "
)
[4] => Array
(
[0] => 2
[1] => Things 'Punk' Loves
)
)