【问题标题】:Which is better to match any character, (.|\n|\r) or [\s\S]? [duplicate]哪个更好地匹配任何字符,(.|\n|\r) 或 [\s\S]? [复制]
【发布时间】:2020-01-04 19:46:17
【问题描述】:

我想使用正则表达式匹配任何以“abc”开头并以“xyz”结尾的多行文本,我有两个正则表达式模式可供选择:

  1. ^abc(.|\n|\r)*xyz$
  2. ^abc[\s\S]*xyz$

除了性能之外,两者是否等价?

哪个更好,为什么?

【问题讨论】:

  • 现在是第二个,因为它不使用捕获的组:p
  • 两者是不同的模式
  • 对于“哪个更好以及为什么”没有独立于引擎的答案。根据regex标签的规则:“由于正则表达式没有完全标准化,所有带有这个标签的问题还应该包含一个标签,指定适用的编程语言或工具。”
  • @joanis 有两个答案清楚地解释了所问的问题,tim's 答案谈到了两种模式之间的差异,@Toto 的答案谈到了性能
  • 答案是:都不用,它们都不好。使用.,带有必要的选项(在Ruby 中通常是s,或m)或不使用(在所有POSIX 风格中)。在 JS ECMAScript 旧版本中,有 [^]. = 好,[\s\S] = 一般,(.|\n|\r) = 最差。

标签: regex regular-language


【解决方案1】:

您最好的选择是告诉任何正则表达式库/引擎点应该匹配所有字符,包括行分隔符。几乎我所知道的每个正则表达式实现都有这个功能:它通常是一个名为 DOT_ALLMULTILINE 的标志或一个名为“点匹配换行符”或类似的选项。

如果这不是一个选项,请选择您发布的第二个选项:字符类比使用 | 运算符更有效。

【讨论】:

  • 两者除了性能是等价的吗?
  • . 匹配除\n 或除\r\n 之外的所有内容的任何引擎中,它们是等价的。我知道的所有引擎都是如此。
【解决方案2】:

对于“与引擎无关的答案”,我会选择您的第二个选项:^abc[\s\S]*xyz$ 仅仅是因为字符类应该比替代更有效(尽管这可能理论上取决于引擎)组。

换句话说,与使用^abc(.|\n|\r)*xyz$ 相比,所讨论的正则表达式引擎使用^abc[\s\S]*xyz$ 匹配结果所需的步骤更少。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 2011-07-23
    • 2019-12-12
    相关资源
    最近更新 更多