2012-03-21 163 views
65

這裏是一個正則表達式我創建在JavaScript中使用:正則表達式中方括號和括號之間的區別是什麼?

var reg_num = /^(7|8|9)\d{9}$/ 

這裏是另外一個由我的團隊成員建議。

var reg_num = /^[7|8|9][\d]{9}$/ 

的規則是驗證電話號碼:

  • 它應該只有10個數字。
  • 的第一個號碼被認爲是任何的7,8或9
+13

你的團隊成員應該閱讀一個基本的正則表達式教程。第二對括號是多餘的,'|'是錯誤的 - 那個正則表達式會驗證字符串'「| 123456789」'。 – 2012-03-21 09:51:32

+0

'[\ d]'也是荒謬的,直接使用'\ d'。因爲'\ d'是[1234567890]' – Eddy 2016-07-19 06:18:11

回答

74

這些正則表達式是等效的(用於匹配目的):

  • /^(7|8|9)\d{9}$/
  • /^[789]\d{9}$/
  • /^[7-9]\d{9}$/

解釋:

  • (a|b|c)是一個正則表達式 「OR」,意思是 「A或B或C」,雖然支架的存在下,必要的OR,也捕獲位數。要嚴格等效,您需要編碼(?:7|8|9)以使其成爲捕獲組。

  • [abc]是 「字符類別」,意思是 「從A,B或C的任何字符」(字符類可以使用範圍,例如[a-d] = [abcd]

的原因,這些正則表達式是相似是一個字符類是一個「或」的簡寫(但只適用於單個字符)。在另一種情況下,你也可以做一些類似(abc|def)的東西,它不會翻譯成字符類。

+24

'(7 | 8 | 9)'和'[789]'的縮寫,並不等同,因爲第一個是捕獲,而後者不是。 '(?:7 | 8 | 9)'相當於另一方面(我想你當然知道......)。 – hochl 2012-03-21 09:55:28

+0

我看到這個正則表達式:'[<<|>> | \] \] | \ [\ []''。由於上下文,我知道正則表達式試圖匹配'<<' or '>>或'[['或']]'。但是根據你所說的,它應該與'<' or '>'或'['或']'匹配。如果在'[]'之間使用'|',那麼括號的行爲是否有所不同? – 2017-11-14 20:39:29

+1

@DanielKaplan不要在字符類[']內使用'|',除非你想匹配管道字符本身。在字符類中複製字符也沒有作用 - 字符類是字符列表,並且將恰好匹配其中的一個字符。我的猜測是你想要一個*組*,它使用正常的圓括號:'(<<|>> | \] \] | \ [\ [)' – Bohemian 2017-11-14 21:35:43

8

前2個例子的行爲非常不同,如果你正在用某物替換它們。如果您在此匹配:

str = str.replace(/^(7|8|9)/ig,''); 

您將用空字符串替換7或8或9。

如果您在本

str = str.replace(/^[7|8|9]/ig,''); 

匹配你將取代789或豎線!!!!由空字符串。

我剛剛發現困難的方式。

+3

歡迎來到SO!替換或匹配,這顯然是錯誤的。很多人犯了這個錯誤,而且他們通常會逃避 - 多年來,有時候 - 因爲他們的輸入字符串從不包含管道('|')。 – 2013-06-20 19:15:22

40

您的團隊的建議是差不多沒錯,除了他犯的錯誤。一旦你找到原因,你將永遠不會忘記它。看看這個錯誤。

/^(7|8|9)\d{9}$/ 

此作用:

  • ^$表示錨定的比賽,它斷言在這些錨定件之間的子模式是整個匹配。只有在子模式與其全部匹配時,字符串纔會匹配,而不僅僅是一個部分。
  • ()表示捕獲組
  • 7|8|9表示匹配7,89中的任一個。它通過變更來做到這一點,這是管道運營商|所做的 - 在變更之間交替。這在交替之間回溯:如果第一次交替不匹配,那麼在交替匹配期間指針位置移動之前,引擎必須返回,以繼續匹配下一次交替;角色類別可以按順序前進觀看這場比賽對正則表達式引擎禁用優化:
Pattern: (r|f)at 
Match string: carat 

alternations

Pattern: [rf]at 
Match string: carat 

class

  • \d{9}九個位數相匹配。 \d是一個簡短的元字符,它可以匹配任何數字。
/^[7|8|9][\d]{9}$/ 

看看它做什麼:

  • ^$表示錨定的比賽也是如此。
  • [7|8|9]字符類別。列表7,|,8,|9中的任何字符都可以匹配,因此|被錯誤地添加。這匹配沒有回溯。
  • [\d]是隱藏元字符\d的字符類。結合使用字符類和單個元字符是一個壞主意,順便說一下,因爲抽象層可能會降低匹配速度,但這只是一個實現細節,僅適用於少數正則表達式實現。 JavaScript不是一個,但它確實使子模式稍長。
  • {9}表示先前的單個構建體總共重複九次。

最佳的正則表達式是/^[789]\d{9}$/,因爲/^(7|8|9)\d{9}$/捕獲不必要強行對大多數正則表達式實現性能下降(恰好是一個考慮的問題使用關鍵字var代碼,這可能是JavaScript的)。使用在PCRE上運行的來進行preg匹配會優化缺乏回溯,但是我們也不在PHP中,所以使用類[]而不是|可以提供性能獎勵,因爲匹配不會回溯,因此兩個匹配並且比使用以前的正則表達式失敗得更快。

+1

只是出於興趣,截圖來自哪個程序? – 2015-10-12 07:56:40

+5

http://regex101.com – Unihedron 2015-10-12 11:45:34

相關問題