【问题标题】:Regex must contain specific letters in any order正则表达式必须包含任何顺序的特定字母
【发布时间】:2013-09-05 18:07:34
【问题描述】:

我一直在尝试验证 VB.net 中的一个字符串,该字符串必须包含这三个字母,没有特定的顺序,并且不需要彼此相邻。 ABC

我可以使用 LINQ 轻松做到这一点

MessageBox.Show(("ABC").All(Function(n) ("AAAABBBBBCCCC").Contains(n)).ToString)

但是,在 Google 和 SO 搜索了一个多星期后,我完全被难住了。我最接近的模式是".*[A|B|C]+.*[A|B|C]+.*[A|B|C]+.*",但AAA 也会返回true。我知道我可以在尝试一周后使用其他方法来做到这一点我真的很想知道是否可以使用 One 正则表达式。

【问题讨论】:

  • 您需要正则表达式有什么原因吗?它总是只有一组 3 个字符吗?
  • 我正在尝试学习如何使用正则表达式。为了学习一个人必须为他/她自己设定任务。感谢您抽出宝贵时间回复:)
  • 您可以尝试不同的问题来学习正则表达式。虽然可以解决这个问题,正如 Jerry 所展示的那样,但这对于正则表达式来说并不是一个特别好的问题(许多字符串库甚至提供了 ContainsAll 方法)。

标签: regex vb.net


【解决方案1】:

您的原始模式将不起作用,因为它将匹配任意数量的字符,后跟一个或多个 ABC| 字符,然后是任意数量的字符,然后由一个或多个 ABC| 字符,后接任意数量的字符,后接一个或多个 ABC|字符,后跟任意数量的字符。

我可能会使用你已经编写的代码,但如果你真的想使用正则表达式,你可以使用一系列lookahead assertions,像这样:

(?=.*A)(?=.*B)(?=.*C)

这将匹配任何包含ABC 的字符串,顺序不限。

【讨论】:

  • 感谢您花时间解释我的模式并提供示例。
  • 你应该提到前瞻是零宽度匹配并且应该跟一个匹配的模式(例如一个.+跟随前瞻):(?=.*A)(?=.*B)(?=.*C).+
  • @bobobobo 不一定。零长度字符串是一个有效的模式,所以如果您只是测试匹配(并且您不关心实际捕获匹配),那么仅使用零宽度断言就可以正常工作。见repl.it/repls/BumpyFoolhardyBarnswallow
【解决方案2】:

您可以利用积极的前瞻:

^(?=.*A)(?=.*B)(?=.*C).+

(?=.*A) 确保字符串中的某处有一个 A,并且相同的逻辑适用于其他前瞻。

【讨论】:

  • 天哪。我离得有多近。我了解分组,但您介意解释一下吗(?= 那是正面的样子吗?
  • @SamJohnson 是的!如果您问我,这有点“高级”正则表达式语法。我自己花了一段时间才像现在一样理解它们。基本上,只有当括号内的条件匹配时,您才会得到匹配。因此,如果字符串匹配.*A(即任何字符,然后是A,它将匹配)。连续应用 3 就像检查 3 个条件并确保它们在继续之前得到满足。这是对前瞻的粗略描述,但您可以获取更多信息here
  • 非常感谢您的时间和精力。我接受了你的回答。我真的很感激。
  • @SamJohnson 不幸的是,您只能“接受”一个答案,这就是网站的运作方式^^;但如果你接受 p.s.w.g 的回答也没关系。我可能应该提到为什么你的正则表达式不能正常工作。
【解决方案3】:

您可以使用零宽度前瞻。如果不符合特定标准,前瞻非常适合消除匹配可能性。

例如,让我们使用单词

untie queue unique block unity

从基本的单词匹配开始:

\b\w+\b

要要求与\w+ 匹配的单词以un 开头,我们可以使用正向预测

\b(?=un)\w+\b

这是什么意思

  • \b 匹配一个空格
  • (?=un) 有“un”这个字母吗?如果不是,则不匹配。如果是这样,那么可能匹配。
  • \w+一个或多个单词字符
  • \b 匹配一个空格

如果不满足内部表达式,则正向前瞻会消除匹配的可能性。它适用于它之后的正则表达式。所以(?=un) 适用于上面的\w+ 表达式并要求它以un 开头。如果不匹配,则\w+ 表达式将不匹配。

匹配任何un开头的单词怎么样?只需使用“负前瞻”

\b(?!un)\w+\b
  • \b匹配一个空白
  • (?!un) 有“un”这个字母吗?如果 如此,则不匹配。如果不是,则可能匹配。
  • \w+一个或多个单词字符
  • \b 匹配一个空格

因此,对于字符串中至少有 1 个 A、1 B 和 1 个 C 的要求,类似于

(?=.*A)(?=.*B)(?=.*C).+

有效,因为它说:

  • (?=.*A) - 它是否有 .* 后跟 A 的任何字符?如果是,则可能匹配,如果不是不匹配。
  • (?=.*B) - 它是否有 .* 后跟 B 的任何字符?如果是,则可能匹配,如果不是不匹配。
  • (?=.*C) - 它是否有.* 后跟 C 的任何字符?如果是,则可能匹配,如果不是不匹配。
  • .+ 如果满足上述 3 个前瞻要求,则匹配任何字符。如果不匹配,则不匹配任何字符(因此不匹配)

【讨论】:

    【解决方案4】:

    它必须是正则表达式吗?这是没有人可以轻松解决的问题。

    我从未在 VB 中编程过,但我确信有一些辅助函数可以让您获取一个字符串,并查询其中是否出现字符。

    如果 str 是你的字符串,可能是这样的:

    str.contains('A') && str.contains('B') && str.contains('C')

    【讨论】:

    • “它必须是一个正则表达式吗?没有一个也可以很容易地解决这个问题。”我不是还没有提供一个不使用正则表达式的工作示例吗?
    猜你喜欢
    • 2017-04-04
    • 2011-11-30
    • 2019-10-07
    • 2019-09-15
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多