C# 中的正则表达式,否定后向表达式

Posted

技术标签:

【中文标题】C# 中的正则表达式,否定后向表达式【英文标题】:Regex in C# , Expression in negative lookbehind 【发布时间】:2014-04-17 23:33:32 【问题描述】:

我正在尝试编写一个表达式来匹配前面有奇数个问号的单引号。

我发现了一个否定的后向表达式来匹配单个问号

pattern (?<!\?)'

aaa?'aaa   match
aaa'aaaa   not match
aaa??'aaa  match --wrong

但我需要的是检测奇数个问号,而不仅仅是一个。 我试着把它写成(?&lt;!\?(??))',但是没有用。

我想要的结果是

aaa?'aaaa  match
aaa??'aaaa  not match
aaa???'aaaa  match
aaa????'aaaa  not match
aaa?????'aaaa  match

【问题讨论】:

【参考方案1】:

您要查找的正则表达式是(?&lt;=(^|[^?])(\?\?)*\?)'

让我们分解一下(我将其改为正面):

(^|[^?]) not a question mark (possibly also start of string, i.e. nothing)
(\?\?)*  any number of question mark pairs
\?       a single question mark

所以为了匹配引用,它必须以相反的顺序在这些标记之前。应该清楚的是,对于某些 N >= 0,这会强制前面问号的数量恰好为 2N + 1。

【讨论】:

也应该检查可能的输入开头,否则只有当它们不在字符串开头时才匹配。【参考方案2】:

我认为您不需要为此匹配使用任何环视。试试这个:

([^\?]|^)\?(\?\?)*([^\?]|$)

它正在检查? 符号是否在非问号符号之间或字符串开头的末尾。

虽然我不确定像aaa?????'aaaa?? 这样的输入会发生什么

【讨论】:

关于环视的好建议:它永远不应该是您使用的第一个工具,尤其是环视。但这里有它的合法用途。将您的 ([^\?]|^) 更改回 (?&lt;!\?) 就像 OP 一样,您不必将字符串的开头作为特殊情况处理。此外,如果您再次阅读该问题,您会发现您的 ([^\?]|$) 应该只是 '(撇号/单引号)。

以上是关于C# 中的正则表达式,否定后向表达式的主要内容,如果未能解决你的问题,请参考以下文章

python里使用正则表达式的后向搜索肯定模式

python里使用正则表达式的后向搜索肯定模式

python里使用正则表达式的后向搜索肯定模式

用于否定字符类的 C# 正则表达式,除非字符彼此相邻

正则表达式之基础

非固定长度的正则表达式负回溯