2014-10-01 47 views
0

我有一個關於正則表達式的快速問題。在模式匹配中是否存在 。*和(。*)之間的差異?分組 似乎是多餘的。我問這個問題是因爲我在Apache的RewriteCond或RewriteRule表達式中看到兩種形式 。正則表達式:。*與(。*)和字符類的最佳實踐

此外,我想知道是否考慮 是一種很好的做法,可以在匹配 圖案時對字符類進行分組。 ab \ scd與ab(\ s)cd。這裏後者似乎更直觀了 。

+0

'(。*)'圍繞'。*'匹配的任何內容形成一個組。 – 2014-10-01 02:27:04

回答

1

(.*)創建一個組,它可以重新匹配或在以後替換爲\1或類似的。 (數字是從左到右的組的編號。)()是什麼使其成爲一個組,因此.*將匹配相同,但不是組。

匹配組使用更多的內存,並需要更長的時間,所以應該避免,除非組是必要的。

如果您不需要記住內容,則可以使用更少的內存更快地使組工作。在第一個括號之後加上?:,例如(?:this)而不是(this)

以下是必要分組的一些例子:

  • (.*),(.*)圖案的\1\t\2取代,取代昏迷分隔一對與製表符分隔之一。你需要團體進行替代。
  • (abc)*,其連續匹配任意數量的abcs,例如, abcabcabcabc。該小組需要說明的是全部abc這是重複的,而不僅僅是c。 (注意,這是因爲(?:abc)*更有效。)

至於字符類,沒有理由做一團了字符類的。 ab(\s)cd將會像ab\scd一樣匹配,但前者速度要慢得多並且使用更多內存。如果你想爲讀者提供更多的清晰度,用方括號(通常用於定義一個自定義字符類)包圍字符類通常可以不需要額外的費用或最小的額外費用。例如。 ab[\s]cd。 (感謝Hobbs提出這個建議。)

+0

大多數正則表達式允許在括號內的字符類中使用反斜槓字符類,所以你可以在(可能)沒有成本的情況下使用'[\ s]'來提高可讀性。 – hobbs 2014-10-01 03:34:59

+0

@ hobbs的確如此。唯一的額外費用是在編譯時,這是最小的。我會添加它作爲一個建議。 – 2014-10-01 22:46:38

0

如果您不需要參考組(例如捕獲組的真正目的是能夠在替換或重寫目標中引用它)或將量詞應用於該組,則唯一的真正的區別在於可讀性。

由於正則表達式引擎將不得不在內存中保留組匹配,所以如果你擔心這種事情,你總是可以將組合變成非捕獲組,這些組合都是?:,即(?:.*) ,但最終會在正則表達式中添加更多特殊字符,並使其不易讀。

最後,這部分是偏好問題,但總的來說,我沒有看到許多人(如果有的話)故意寫出冗餘捕獲組。

1

忘記正則表達式良好實踐的概念*。一個無用的捕獲組浪費內存,並且不會讓你的模式更具可讀性。只有在需要時才使用它。

關於捕獲組和非捕獲組之間的表現:根據所使用的正則表達式引擎,您可能會有很大的差異。爲了給出一個想法,非捕獲組可以比PHP中的捕獲組快150倍。

*正則表達式被構建爲儘可能高效。它只取決於你正在嘗試做什麼以及你正在使用哪個引擎。模式的構建取決於正則表達式引擎機制。在這種背景下,嘗試應用「良好實踐」並不相關。但是,憑藉這些經驗,您將在某些情況下使用衆所周知的食譜。

+0

'非捕獲組可以比PHP中的捕獲組快150倍。它是否包括做子串操作的時間? – nhahtdh 2014-10-01 05:02:16