【问题标题】:Leading Characters prevent Regex match?前导字符阻止正则表达式匹配?
【发布时间】:2015-03-06 05:07:13
【问题描述】:

如果我知道我需要的正则表达式功能的名称,我会有一个更好的标题。

作为一项验证任务,我需要验证文本流是否仅包含与我建立的正则表达式模式匹配的部分,无论它发生多少次。例如,如果我的模式是“foo”并且我有字符串

 "foo foofoo" 

结果应该是三个匹配并且没有其他不匹配的文本。相反,字符串

"foo foo fooo"  

应该返回三个匹配,但我需要检测剩余的可打印字符 'o' 不匹配。我的第一个想法是将管道字符用于“或”逻辑,例如“(?:foo)|(\S)”,我以为我已经对其进行了排序,但是字符串

"-foo foo foo" 

只匹配两次。似乎前导字符会导致引擎跳到表达式的右侧,并且由于它的定义很广泛,它会一直捕获到下一个单词中断。显然,我的心理表征并不能反映引擎的运行方式。我哪里错了?

【问题讨论】:

  • 您需要实际的匹配数,还是只是为了检测存在不匹配的非空白文本?
  • 我认为这需要两个不同的正则表达式操作。首先进行测试以验证匹配后没有任何剩余,然后进行第二次校准以进行匹配并提取数据。这有点像基于集合的“除外”逻辑。
  • 这个问题是相关的,但对我来说还不是解决方案。 stackoverflow.com/questions/406230/…

标签: regex


【解决方案1】:

您想搜索"foo",以及它后面的任何字符,直到下一个 foo。为了做到这一点,您需要一个否定的前瞻断言(检查“某些东西后面没有其他东西”)。所以你的正则表达式将是"foo.*?(?!foo)"

【讨论】:

  • 这是一个比我的示例更好的模式,但我需要相反的模式 - 该模式排除的文本集。这就是为什么我认为需要涉及管道交替字符的原因。
  • 我不知道有什么方法可以仅使用正则表达式来查找与子模式不匹配的位。在任何编程语言中都可以轻松处理字符串以执行您的请求(您只需在 foo 上使用空字符串进行全局替换,剩下的不匹配字符即可)。
【解决方案2】:

好像你想要这样的东西,

(?<![^\w\s])foo

DEMO

【讨论】:

    【解决方案3】:

    你可以这样做:

    \b(?:foo)\b|\b(?:foo)+\b
    

    Demo

    也许更好:

    \b(?:foo)\b|\b(?:foo){2,}\b
    

    Demo 2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      相关资源
      最近更新 更多