【问题标题】:Regular expression with optional part and negative lookahead带有可选部分和负前瞻的正则表达式
【发布时间】:2018-01-09 19:58:57
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你的意思是你只需要检查它是否匹配吗?喜欢A(?!\s*B)?或者您是从较长的字符串中提取这些子字符串吗?请说清楚。也许你需要(?>A\s*)(?!B)?此外,如果您发布相关的 C# 代码也会有所帮助。
  • 更新了帖子。我没有捕获值,但需要检查输入中是否有与模式匹配的子字符串。
  • 你想匹配"A "吗?

标签: c# regex regex-negation


【解决方案1】:

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

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" 和 "B" 是相同的字符串,则它不起作用,例如(?>A\s*)(?!A) 仍然匹配 A A。你知道为什么吗?
  • (?>A\s*)(?!A) 仍然匹配 A A,因为该模式找到了部分匹配项,因此匹配第二个 A 后面没有 0+ 个空格,然后是 A。请准确说明您在做什么。
  • @Impworks 我认为您正在尝试匹配没有 A\s*B 模式的字符串。为什么不直接使用!Regex.IsMatch(s, @"A\s*B")?如果必须有A\s*,则像Regex.IsMatch(s, @"^(?!.*A\s*B).*A")一样组合起来
【解决方案2】:

更新: 根据下面的评论,使用此模式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)

【讨论】:

  • .NET 正则表达式引擎不支持所有格量​​词。
【解决方案3】:

该尝试不起作用,因为它在" B" 之前匹配"A",我建议尝试采用否定方法,并编写A\s*B 并使用所有不匹配的行。例如使用 grep grep -v "A\\s*B"

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2011-10-14
    相关资源
    最近更新 更多