2013-03-11 51 views
1

我想用正则表达式来查找不具有属性的不完整的xml标签。到目前为止,我设法提出了这个正则表达式</?\s*([a-zA-Z0-9]?:\s+)?[a-zA-Z0-9]*(?!>),但这并不能解决问题。 在XML像这样的: <abc> </abc> <ab> </ab <s:ab正则表达式查找不完整的xml标签在c#

我想匹配</ab<s:ab(因为他们都缺乏“>”结尾)。有没有办法在c#中使用正则表达式来做到这一点?

+6

正则表达式不适用于此 - 您应该使用XML解析器/验证程序。 – Oded 2013-03-11 16:36:22

+0

您无法用一个正则表达式涵盖所有可能性。你最好遵循Oded的建议。 – m0skit0 2013-03-11 16:37:44

+0

我不认为有这么多的可能性。这些是我感兴趣的标签类型: 2013-03-11 16:50:17

回答

0

如果您只是试图在单个xml文件中查找错误,请尝试在Google Chrome浏览器中打开它 - 它会显示错误所在的行。

但是,如果你有很多文件需要在代码中处理,那么你需要比正则表达式更强大的东西。

1

你很近。您的主要问题是,当负向预测失败时,模式回退。您可以通过将该部分放在非追溯原子组中的lookahead之前来避免这种情况:(?>no backtracking in here)

例如:

(?xi)     # turn on eXtended (ignore spaces/comments) and case-Insensitive mode 
(?>      # don't backtrack 
    < /?     # tag start (no space allowed after it) 
    [a-z0-9]+    # tag name/space 
    (?: : [a-z0-9]+)? 
    \s*     # optional spaces 
) 
(?! >)     # no ending 

注意,这将在<foo bar>匹配<foo

0

正如人们所说,这可能是徒劳的努力 - 因为XML不是一种常规语言。然而,你的问题的一部分是你的前瞻。你只能确保它没有紧接着一个闭角尖括号 - 这意味着即使你不想要它们,<ab<abc>也会匹配。所以你需要将整个标签结构包含在你的lookahead中。

要得到你给了,我可以使用正则表达式的确切数据匹配:

#</?([a-z]?:)?[a-z]*(?!/?([a-z]?:)?[a-z]*>)# 

你可以在行动here看到。这里的关键在于确保正则表达式引擎在任何时候都不会回溯(通过放弃一个字符)来验证lookahead。还有其他方法可以做到这一点 - 例如possessive quantifiers,它在正常的回溯过程中拒绝放弃匹配的标记,但标准的.NET引擎不支持所有格匹配。它确实支持一个原子组 - 它的行为方式相同,但使用一个组而不是一个量词。你可以看到here,我已经将标记的整个开头包裹在一个原子组中。 ((?> ...)

#(?></?([a-z]?:)?[a-z]*)(?!>)# 

你可以自由输入自己的正则表达式如何标签应该被格式化,但我必须说,这正则表达式已经推动可读码极限,摆弄合法的XML标签名称将会朝这个方向进一步推进。不过,我希望这有助于澄清错误。

+0

哈希值是什么?这不是PHP,不需要双引号。 – Qtax 2013-03-11 19:08:51

+0

@Qtax在Perl兼容正则表达式中使用分隔符是相当标准的。 PHP不是唯一的语言。 Perl(很明显)和Javascript将它们嵌入语言中(尽管Javascript只允许正斜杠)。 – FrankieTheKneeMan 2013-03-11 23:34:18

+0

你是双/嵌套在这里引用。这种愚蠢只会在PHP中完成。其他语言为正则表达式(Perl,JS,Ruby等)提供了特殊的引用构造(例如'/ regex /'),或者只使用常规字符串引号(Java,C++等)。在Perl中,你可以使用任何你想引用表达式的字符。我的观点是:1)C#不会像那样引用。 2)您已经在标记标记中引用了表达式,不需要再次引用它(尽管如此,仍然以不支持的格式)。 3)不要传播PHP正则表达式引用疯狂 – Qtax 2013-03-12 05:07:51