我对正则表达式有一个快速的问题。在那儿 模式匹配中。*和(。*)之间的区别?分组 似乎多余。我问这个问题,因为我看到了两种形式 在Apache的RewriteCond或RewriteRule表达式中使用。
此外,我想知道是否考虑到了 在匹配时将字符类分组是一种很好的做法 模式,例如ab \ scd与ab(\ s)cd。后者似乎在这里 更直观。
答案 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)
如果您不需要引用该组(例如,捕获组的真正目的是能够在替换或重写目标中引用它)或对其应用量词,那么唯一真实的区别在于可读性。
还有一个很小的性能损失,因为正则表达式引擎必须将组匹配保留在内存中,因此如果您担心这些事情,您可以随时将组转换为非捕获组?:
,即(?:.*)
,但这最终会在正则表达式中添加更多特殊字符并使其可读性降低。
最后,这部分是偏好问题,但总的来说,我没有看到很多人(如果有的话)故意写出冗余的捕获组。