【问题标题】:Best way to match all patterns in a string?匹配字符串中所有模式的最佳方法?
【发布时间】:2012-04-10 21:45:13
【问题描述】:

匹配给定字符串中存在的所有一组模式的最佳方法是什么。例如,假设我有数千个中等长度的字符串(每个大约 30-50 个字符)的集合。用户需要能够指定一组模式(甚至不是模式,实际上只是一系列字符),每个字符串都将被评估,字符串必须包含所有指定的模式。

因此假设用户想要评估以下模式:

123
xyz
abc

类似的字符串:

john_smith_123456_abcdef_9999_tuv 

会是假的,因为它只包含 3 个中的 2 个,而字符串如下:

jane_doe_abcdef_123_9999_tuvwxyz 

应该是真的,因为它包含所有 3 个

首先,regex 还是 string.Contains()?还是有一个权衡点,其中一个表现比另一个更好?其次,假设正则表达式是可行的方法,那么在这种情况下使用哪种正则表达式的最佳类型是?

非常感谢!

【问题讨论】:

标签: c# regex string


【解决方案1】:

您要查找的是大字符串中的特定字符串,对吧?如果是这样,正则表达式在这里不会对你有多大好处。当然,您可以做一些前瞻性的事情,但是您并没有真正获得任何东西——无论是在可读性方面还是在性能方面。正则表达式用于在文本中查找 patterns,而不是 substrings。

只需遍历列表、数组等...并使用Contains 查找每个子字符串。

【讨论】:

    【解决方案2】:

    以下正则表达式将起作用:

    ^(?=.*123)(?=.*xyz)(?=.*abc).*$
    

    这使用lookaheads 确保您要查找的三个子字符串包含在字符串中的某个位置,然后如果找到所有子字符串,则使用.* 消耗整个字符串。

    【讨论】:

    • 好。与 Regex.Escape 结合使用,可以针对输入字符串列表以编程方式生成正则表达式。
    • 感谢您的表达...但我倾向于相信,鉴于我将始终搜索纯子字符串,而不是 string.Contains() 将胜过最聪明的正则表达式的表达式,你会同意还是认为前瞻会产生足够的影响?
    【解决方案3】:

    正则表达式几乎总是简单匹配的较慢选项。您应该使用String.Contains(),除非您确实需要正则表达式功能。如果只允许用户输入实际字符串进行测试,则不需要正则表达式。

    【讨论】:

      【解决方案4】:

      对于这样一个简单的任务,正则表达式似乎有点过头了。您实际上并不是在寻找 pattern 而是寻找子字符串,在这种情况下,String.Contains() 非常适合这项工作(假设您没有没有告诉我们的“隐藏”要求大约)。

      【讨论】:

        【解决方案5】:

        没有经验法则来决定基于正则表达式的解决方案何时会太慢。事实上,没有理由期望正则表达式比任何其他技术都慢。像任何其他工具一样,如果您有能力使用它并且它似乎提供了最简单的方法,请继续尝试。当您编写了足够多的代码以使测试变得有意义时,请对其进行基准测试。

        此外,如果模式如此简单以至于您可以使用Contains(),那么也很少有机会弄乱正则表达式并创建 resonance cascade 灾难性的回溯场景。请记住:正则表达式不会炸 CPU,正则表达式作者会这样做。 :D

        我倾向于同意您关于FJ 提出的多重前瞻方法;这份工作可能太慢了。它实际上与多次调用Contains() 相同,但由于回溯会产生额外的开销。无论如何都值得测试,但我会先尝试这种方法:

        ^(?>(?:123()|xyz()|abc()|.)+$\1\2\3)
        

        前瞻方法必须扫描每个搜索词的整个字符串,而这个正则表达式只扫描一次,并且从不回溯。每次它在一个搜索词上得到命中时,紧随该词的捕获组被称为参与了匹配,即使它什么也没捕获。当到达字符串末尾时,如果该组参与匹配,则每个反向引用再次“不匹配”;否则报告失败,整体匹配失败。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-16
          • 1970-01-01
          • 2017-03-29
          • 1970-01-01
          • 1970-01-01
          • 2011-09-03
          相关资源
          最近更新 更多