正则表达式:。*与(。*)和字符类最佳实践

时间:2014-10-01 02:18:38

标签: regex .htaccess

我对正则表达式有一个快速的问题。在那儿 模式匹配中。*和(。*)之间的区别?分组 似乎多余。我问这个问题,因为我看到了两种形式 在Apache的RewriteCond或RewriteRule表达式中使用。

此外,我想知道是否考虑到了 在匹配时将字符类分组是一种很好的做法 模式,例如ab \ scd与ab(\ s)cd。后者似乎在这里 更直观。

3 个答案:

答案 0 :(得分:1)

(.*)创建一个组,可以在以后重新匹配或替换为\1或类似组。 (该数字是该组的编号,从左到右。)()是使其成为一个组的原因,因此.*将匹配相同的但不是“a”组。

匹配组使用更多内存,并且需要更长时间,因此除非需要这些组,否则应该避免使用。

如果您不需要记住内容,则可以使用更少的内存使群组更快地工作。只需在第一个括号后添加?:,例如(?:this)代替(this)

以下是必要分组的一些示例:

  • (.*),(.*)模式,替换为\1\t\2,用替换为制表符的对替换了逗号分隔对。您需要组来进行替换。
  • (abc)*,其中连续匹配任意数量的abc,例如abcabcabcabc。该小组必须告知其重复abc所有,而不仅仅是c。 (请注意,这更有效(?:abc)*。)

对于字符类,没有理由用字符类创建一个组。 ab(\s)cd将匹配ab\scd,但前者速度更慢,占用内存更多。如果您想要为人类读者提供更多清晰度,那么使用方括号(通常用于定义自定义字符类)围绕字符类通常可以在没有或只需要很少的额外成本的情况下完成。例如。 ab[\s]cd。 (感谢Hobbs建议这一点。)

答案 1 :(得分:1)

忘记正则表达式 * 的良好实践概念。一个无用的捕获组会浪费内存,而不会让你的模式更具可读性。只在您需要时使用它。

关于捕获组和非捕获组之间的性能:根据您使用的正则表达式引擎,您可能会有很大差异。要提出一个想法,非捕获组可以比PHP中的捕获组快150倍。

* 构建正则表达式是最有效的。它只取决于您尝试做什么以及您正在使用哪种引擎。模式的构建取决于正则表达式引擎机制。在这种情况下,尝试应用"良好实践"并不是非常重要。但是,根据经验,您将在某种情况下应用熟知的食谱。

答案 2 :(得分:0)

如果您不需要引用该组(例如,捕获组的真正目的是能够在替换或重写目标中引用它)或对其应用量词,那么唯一真实的区别在于可读性。

还有一个很小的性能损失,因为正则表达式引擎必须将组匹配保留在内存中,因此如果您担心这些事情,您可以随时将组转换为非捕获组?: ,即(?:.*),但这最终会在正则表达式中添加更多特殊字符并使其可读性降低。

最后,这部分是偏好问题,但总的来说,我没有看到很多人(如果有的话)故意写出冗余的捕获组。