【问题标题】:Regex to match when a string is present twice字符串出现两次时匹配的正则表达式
【发布时间】:2011-11-18 17:25:27
【问题描述】:

我不擅长正则表达式,我只是不经常使用它们,以至于我无法记住两次使用之间的语法。

我正在使用 grepWin 搜索我的文件。我需要进行搜索以返回具有给定字符串的文件两次

因此,例如,如果我搜索“how”一词,则文件 1 将不匹配:

你好
你今天好吗?

但文件二会:

你好
你今天好吗?

我很好,你好吗?

有谁知道如何制作一个匹配的正则表达式?

【问题讨论】:

  • 如果搜索字符串必须是一个变量,那么这对于正则表达式是不可能的。您需要将它与脚本语言结合起来。如果它不需要可变,那么这个正则表达式可以:how are you.*how are you
  • @Jeff 可以在 JavaScript 正则表达式中引用匹配的组:/(abc)\1/ 匹配 abcabc,但不匹配 abc
  • 只有在“如何”出现完全两次时才必须匹配?如果它出现 3 次或更多次怎么办?

标签: regex


【解决方案1】:

类似的东西(取决于语言和您的具体任务)

\(how.*){2}\

编辑: 根据@CodeJockey

\^(([^h]|h[^o]|ho[^w])*how([^h]|h[^o]|ho[^w])*){2,2}$\

(变得更复杂了) @CodeJockey:感谢 cmets

【讨论】:

  • 这将获得两次或多次how 的文件,但不会排除出现三次或多次的文件
  • @CodeJockey 我也是这么读的。我想知道提问者的意思是否完全两次。
  • 嗯...第二个表达式并没有改善这种情况...第一个表达式正确地断言有两个 how 实例后跟任何(或什么都没有),但它确实不阻止how 的第三、第四、第五等实例出现在文件中 - 换句话说,如果您将修改归因于我,我认为您误解了我的评论
  • +1 实际在 grepWin 中测试并且可以工作(只需删除 ` characters, please, before putting the expression into the search field). Though... {2}` 与 {2,2} 相同,即使手动创建会很痛苦...... :D
  • \ 字符 - 有人知道如何正确使用反引号来转义 \ 吗?
【解决方案2】:

我不知道 grepWin 支持什么,但这是我想出的让某些东西完全匹配两次的方法。

/^((?!how).)*how((?!how).)*how((?!how).)*$/

解释:

/^             # start of subject
  ((?!how).)*  # any text that does not contain "how"
  how          # the word "how"
  ((?!how).)*  # any text that does not contain "how"
  how          # the word "how"
  ((?!how).)*  # any text that does not contain "how"
$/             # end of subject

这可确保您找到两个“how”,但“how”之间以及它们两侧的文本不包含“how”。

当然,您可以用任何字符串替换表达式中的“how”。


如果你想通过只写两次搜索表达式来“简化”,你可以使用反向引用:

/^(?:(?!how).)*(how)(?:(?!\1).)*\1(?:(?!\1).)*$/

Refiddle with this expression

说明:
我添加了?: 以使负前瞻的文本不被捕获。然后我在常规 how 周围添加了括号,以使其成为捕获子模式(第一个也是唯一一个)。

我不得不在第一个前瞻中再次包含“如何”,因为它是一个负面的前瞻(意味着任何捕获不会包含“如何”)并且捕获的“如何”还没有被捕获点。

【讨论】:

    【解决方案3】:

    这比我最初想象的要困难得多,并且需要可变长度的lookbehind,而 grepWin 不支持...

    这个表达式:

     (?<!blah.{0,99999})blah(?=.*?blah)(?!.*blah.*blah)
    

    在 Eclipse 中成功使用,使用“搜索 > 文件”对话框排除具有 1 个和 3 个 blah 实例的文件,并包含恰好具有两个 blah 实例的文件。

    Eclipse 不允许在后视中使用 .*,因此我改用了 .{0,99999}

    使用正确的工具是可能的,但是让它与 grepWin 一起工作并不好(参见上面的答案)。您可以使用其他工具(例如 Eclipse)吗?之后您想对这些文件做什么?

    【讨论】:

    • 如果后视是一个问题,我只使用前瞻。
    • 是的 - 一旦我在请求的产品中测试了@VMykyt 的解决方案并且它有效(尤其是 OP 没有任何明显的兴趣),我就没有打扰过。当我最初解决它时,我的大脑不知何故暂时失去了行首或字符串锚的想法,这应该可以在没有后视的情况下实现:D
    • @Wiseguy 我确实喜欢你的解决方案使用整个单词......无论如何,虽然添加起来并不难,但没有人考虑到 OP 可能只想匹配的事实包含两个how实例的文件,但允许“榴弹炮”或“不知何故”甚至“淋浴”任意次数
    • 真实的故事,不过你可以简单地将搜索词组设为\bhow\b
    • @Wiseguy 就像我说的,“不要太难”......但收益递减(OP 是一个成熟的成员,但可能会回来)
    【解决方案4】:

    这适用于 grep || python,仅当“how”在your_file中存在两次时才会返回匹配项:

    grep "how.*how" your_file
    

    在python中(重新导入):

    re.search(r"how.*how","your_text")
    

    它将返回介于两者之间的所有内容,(点表示任意字符,星表示任意数量的字符),您可以自定义自己的脚本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-18
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2013-07-26
      • 2012-11-17
      • 1970-01-01
      相关资源
      最近更新 更多