具有可选部分和否定前瞻的正则表达式

Regular expression with optional part and negative lookahead

我需要检查字符串是否包含以下模式:以 "A" 开头,后跟零个或多个空格,然后是 "B" 以外的任何内容。

因此,以下必须匹配:"A""AX""A X""A ""A XB"

以下字符串不能匹配:"AB""A B"

我天真的尝试是A\s*(?!B),但它匹配了不受欢迎的"A B"

如果你只需要得到真或假,你可以把\s*放到lookahead中:

Regex.IsMatch(s, @"A(?!\s*B)")

它发现 A 没有 0+ 个空格,后面跟着 B

参见regex demo

在您的模式中,A\s*(?!B),可以在任何 0+ 个空格之后执行否定先行,并且一旦发现未跟随 B 的空格,将返回一个有效匹配项(发生这种情况由于 \s* 量化模式,回溯是可能的)。

如果您需要实际匹配 A 及其后的空格,但如果这些空格后面没有跟 B,请使用我评论中的模式。

(?>A\s*)(?!B)

此模式匹配:

  • (?>A\s*) - 一个原子组,匹配 A,然后是 0+ 个空格 没有回溯到组模式 允许
  • (?!B) - 空格后没有B,否则整个匹配失败。

更新: 根据下面的评论,使用此模式 A\s*B|(A) 并检查组 #1


使用这个模式A\s*+(?!B)\w*Demo

#    A\s*+(?!B)\w*
A           # "A"
\s          # <whitespace character>
*+          # (zero or more)(possessive)
(?!         # Negative Look-Ahead
  B         # "B"
)           # End of Negative Look-Ahead
\w          # <ASCII letter, digit or underscore>
*           # (zero or more)(greedy)

或者根据您的尝试,使用此 A\s*+(?!B)

尝试无效,因为它匹配 " B" 之前的 "A",我建议尝试采用否定方法,并写成 A\s*B 并使用所有非匹配线。例如使用 grep grep -v "A\s*B"

如果需要 A 并且有非 A 行你可以搜索两次,grep A | grep -v "A\s*B".