完全匹配任何顺序的字符串

时间:2019-01-19 13:52:46

标签: regex regex-lookarounds

我想用以下模板匹配字符串:

<el key1="val1" key2="val2" />

我可以将它们与正则表达式匹配,例如:

^(<el\s+)(?=.*key1=".*".*)(?=.*key2=".*".*)(.*\/>$)

问题是

<el key1="val1" key2="val2" aaa />
<el key1="val1" aa key2="val2" />
<el aaa key1="val1" key2="val2" />

也是匹配项。我想准确地在开头找到^<el\s+,在结尾找到(\/>)$,而在两者之间找到两个\s+keyn=".*"\s+

编辑: (基于评论和答复)键可以是titleuritext。到目前为止,答案的问题在于键可以以任意顺序排列,所以:

<el key1="val1" key2="val2" />
<el key2="val2" key1="val1" />

都是有效的。

2 个答案:

答案 0 :(得分:0)

这是一个可以正常工作的正则表达式

^(<el)\s+(\S+=".*")\s+(\S+=".*")\s+(\/>$)

答案 1 :(得分:0)

您应该真正使用您语言的XML解析器,因为您不想匹配的内容都是无效的XML标记,因此可以轻松排除它们。您只需要检查标记名称为el,并且只有2个属性key1key2

如果您坚持使用正则表达式,则应该使用以下方法:

^<el\s+key1=".*?"\s+key2=".*?"\s+\/>$

此操作与您的尝试之间的主要区别在于,您的尝试使用了太多的超前时间。你为什么要提前使用?正常匹配应该可以。您先寻找key1=".*?",然后贪婪地匹配.*,这似乎很多余。因此,我删除了前行和.*。而且它只匹配您想要的字符串。

如果您还想匹配key2出现在key1之前的字符串,则正则表达式会变得更长:

^<el\s+(?:key1=".*?"\s+key2=".*?"|key2=".*?"\s+key1=".*?")\s+\/>$

这就是为什么我说您应该使用XML解析器。