我如何使这个正则表达式更通用,有时它工作,有时它不工作

时间:2009-06-26 09:17:22

标签: java regex validation robustness

我在java应用程序中使用以下正则表达式。有时它可以正常工作,有时则不然。

<!-- <editable name=(\".*\")?> -->(.*)<!-- </editable> -->

有时我会在它之前/之后有空格,有时候会有文字。标签内的区域也是如此。

主要问题是name =(\“。* \”)?&gt;有时匹配比预期更多。我不确定这是否是明显可以解决的问题,只需查看此代码即可。

4 个答案:

答案 0 :(得分:5)

XML不是常规语言,也不是HTML或任何其他具有“嵌套”结构的语言。不要试图用正则表达式解析它。

Choose an XML parser

答案 1 :(得分:1)

如果name是某种标识符,我会将.*替换为[\w-]*

[^\"]*因此它不会捕获结束双引号。

修改

正如在其他帖子中提到的,您可能会考虑使用简单的DOM遍历,基于XPath或XQuery的评估过程,而不是简单的正则表达式。但是请注意,你仍然需要在过滤过程中使用正则表达式,因为你只能通过对正则表达式测试它们的身体来找到目标注释(因为我怀疑身体在样本中是不断的判断)。

编辑2:

注释正文的前导,尾随或内部空格可能会使正则表达式失败。考虑将\s*放在开头和结尾,再加上类似属性的\s+

<!--\s*<editable\s+name=(\"[^\"]*\")?>\s*-->(.*)<!--\s*</editable>\s*-->

或者在过滤基于XML的搜索时:

"\\s*<editable\\s+name=(\"[^\"]*\")?>\\s*"
"\\s*</editable>\\s*"

编辑3:修复了两次转义。谢谢 Alan M

答案 2 :(得分:1)

正如其他人所指出的那样,与“name”属性匹配的贪婪.*(点星)需要变得非贪婪(.*?)甚至更好,取而代之的是否定的字符类([^"]*)因此无论在正则表达式的其余部分中发生什么,它都不能匹配在结束引号之外。一旦你修复了它,你可能会发现你和另一个点星有同样的问题;你也需要让它变得非贪婪。

Pattern p = Pattern.compile(
    "<!--\\s*<editable\\s+name=\"([^\"]*)\">\\s*-->" +
    "(.*?)" +
    "<!--\\s*</editable>\\s*-->",
    Pattern.DOTALL);

我没有得到你关于空白的评论的重要性。如果它是你正在谈论的换行和/或回车,DOTALL修饰符让点匹配 - 当然,\s也匹配它们。

我是以Java字符串文字的形式写的,以避免混淆你需要反斜杠的地方以及你需要的数量。在“原始”正则表达式中,每个空格短字(\s*)中只有一个反斜杠,并且引号不需要转义("[^"]*")。

答案 3 :(得分:0)

*乘数默认为“贪婪”,意味着它尽可能匹配,同时仍然成功匹配模式。

您可以使用*?禁用此功能,请尝试:

(\".*?\")