1

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

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

4

3 回答 3

1

你很接近。您的主要问题是,当负前瞻失败时,模式会回溯。您可以通过将前瞻之前的部分放在非回溯原子组中来避免这种情况:(?>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<foo bar>.

于 2013-03-11T19:02:24.433 回答
0

正如人们所说,这可能是徒劳的——因为 XML 不是一种常规语言。但是,您的部分问题是您的前瞻性。你只需要确保它后面没有紧跟一个右尖括号——这意味着即使你不想要它们,类似<abof 的东西也会匹配。<abc>所以你需要在你的前瞻中包含整个标签结构。

为了匹配您提供的确切数据,我可以使用正则表达式:

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

您可以在此处查看实际操作。这里的关键是确保正则表达式引擎在任何时候都不能回溯(例如,删除一个字符)以验证前瞻。还有其他方法可以做到这一点 - 例如所有格量词,它拒绝在正常回溯过程中放弃其匹配的标记,但标准 .NET 引擎不支持所有格匹配。它确实支持原子组 - 其行为方式相同,但使用组而不是量词。您可以在这里看到,我已将标签的整个开口包裹在一个原子组中。( (?> ... ))

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

您可以自由输入自己的正则表达式来确定标签的格式,但我必须说这个正则表达式已经在推动代码可读性的极限,而使用合法的 xml 标签名称将进一步推动它在那个方向。尽管如此,我希望这有助于阐明这个错误。

于 2013-03-11T19:05:27.617 回答
0

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

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

于 2013-03-11T16:42:58.220 回答