首頁 > web前端 > js教程 > 關於JS正規表示式的RegExp物件和括號的使用

關於JS正規表示式的RegExp物件和括號的使用

不言
發布: 2018-06-30 13:49:57
原創
1658 人瀏覽過

下面為大家帶來一篇淺談JS正規表示式的RegExp物件和括號的使用。內容還挺不錯的,現在就分享給大家,也給大家做個參考。

RegExp物件的建立:

常規的正規表示式的建立可用直接量,即斜線「/」括起來的字符。但在要求參數變化的環境下,RegExp()建構子是更好的選擇:

var reg1 = /'\w '/g;
var reg2 = new RegExp(' \'\\w \'','g');

對比兩種建立方式,RegExp中的第一個參數為要建立的正規字串,一方面注意,因為不是直接量的表示形式,因此不用斜槓「 / 」括起來了;而是字串中必須要對引號「 ' 」和轉義符號「 \ 」進行二次轉義。

此外,無論是直接量或RegExp()建構函數,都是產生了新的RegExp對象,並將其賦值給變數。

match()與exec()的異同:

#match和exec是正規表示式符合字串的常用方法。兩者實現的功能差不多,有些細微的差別:

1、使用方式

match是字串包裝物件的方法,用法:String.match(RegExp);

exec是正規表示式物件的方法,用法:RegExp.exec(String);

2、傳回的結果

當RegExp沒有設定全域標誌"g" 時:

兩者的回傳結果相同。即無符合值時傳回null,有符合值時傳回一個陣列(令array)。 array[0]為符合的字串,array[1]、array[2]…則對應為正規表示式中圓括號匹配的子字串$1、$2…。同時陣列帶有兩個屬性,array.index表示符合字串的初始位置,array.input表示正在檢索的字串。

當RegExp有設定全域標誌 "g" 時:

match在有值時傳回一個陣列array。數組的每項依次表示匹配到的所有的字串,因此不再有圓括號匹配的子字串了。此時陣列沒有index屬性和input屬性。

exec則與沒有全域標示 "g" 的表現無異。此時傳回的是陣列array,array[0]為目前符合的字串,array[1],array[2]…則為目前符合下的圓括號相符的字串。此時要注意RegExp物件的lastIndex屬性,表示原始字串中符合的字串末端的後一個位置。當沒有進一步的配對結果時,lastIndex屬性置0。因此,可用lastIndex的循環找出所有的符合字串。

支援多次符合的方式:

js 程式碼

var testStr = "now test001 test002";  
var re = /test(\d+)/ig;  
var r = "";  
while(r = re.exec(testStr)) {  
  alert(r[0] + " " + r[1]);  
}
登入後複製

此外也可以用testStr.match(re),但是這樣的話就不能有g的選項,而且只能得到第一個匹配。

1. 正規表示式規則

1.1 普通字元

字母、數字、漢字、底線、以及後邊章節中沒有特殊定義的標點符號,都是"普通字符"。表達式中的普通字符,在匹配一個字串的時候,匹配與之相同的一個字符。

範例1:表達式"c",在匹配字串"abcde" 時,匹配結果是:成功;匹配到的內容是:"c";匹配到的位置是:開始於2,結束於3。 (註:下標從0開始還是從1開始,因當前程式語言的不同而可能不同)

舉例2:表達式"bcd",在匹配字串"abcde" 時,匹配結果是:成功;配對到的內容是:"bcd";匹配到的位置是:開始於1,結束於4。

1.2 簡單的轉義字符

一些不便書寫的字符,採用在前面加 "/" 的方法。這些字符其實我們都已經熟知了。

##/r, /n代表回車與換行符號/t製表符

表達式

#########//############"/" 本身### ############

還有其他一些在後邊章節中有特殊用處的標點符號,在前面加上 "/" 後,就代表該符號本身。例如:^, $ 都有特殊意義,如果要想匹配字串中 "^" 和 "$" 字符,則表達式就需要寫成 "/^" 和 "/$"。

##/^符合^ 符號本身/$符合$ 符號本身

表達式

/.

符合小數點(.)本身

這些轉義字元的匹配方法與"普通字元" 是類似的。也是匹配與之相同的字元。 #正規表示式中的一些表示方法,可以匹配'多種字元' 其中的任何一個字元。例如,表達式 "/d" 可以符合任意一個數字。雖然可以匹配其中任意字符,但只能是一個,不是多個。這就好比玩撲克牌時候,大小王可以代替任一張牌,但只能代替一張牌。 表達式任一個數字,0~9 中的任一任一個字母或數字或底線,也就是A~Z,a~z,0~9,_ 中任一個

範例1:表達式"/$d",在匹配字串"abc$de" 時,匹配結果是:成功;匹配到的內容是:"$d";匹配到的位置是:開始於3,結束於5。

1.3 能夠與'多種字元' 匹配的表達式

##/d

/w

/s

包括空格、製表符、換頁符號等空白字元的其中任一個

範例2:表達式"a./d",在匹配"aaa100" 時,匹配的結果是:成功;匹配到的內容是:"aa1";匹配到的位置是:開始於1,結束於4。 #使用方括號 [ ] 包含一系列字符,能夠匹配其中任何一個字符。用 [^ ] 包含一系列字符,則能夠匹配其中字符之外的任意一個字符。同樣的道理,雖然可以匹配其中任一個,但是只能是一個,不是多個。 ##[ab5@]

.

小數點可以符合除了換行符號(/n)以外的任一字元

舉例1:表達式"/d/d",在匹配"abc123" 時,匹配的結果是:成功;匹配到的內容是:"12";匹配到的位置是:開始於3,結束於5。

1.4 自訂能夠匹配 '多種字符' 的表達式

表達式

###匹配"a" 或"b" 或"5" 或"@"################ ##[^abc]############符合"a","b","c" 以外的任一字元############## ####[f-k]############符合"f"~"k" 之間的任一字母################# #[^A-F0-3]############匹配"A"~"F","0"~"3" 以外的任一個字元####### ########

範例1:表達式"[bcd][bcd]" 匹配"abc123" 時,匹配的結果是:成功;匹配到的內容是:"bc";匹配到的位置是:開始於1,結束於3。

範例2:表達式"[^abc]" 匹配"abc123" 時,匹配的結果是:成功;匹配到的內容是:"1";匹配到的位置是:開始於3,結束於4。

1.5 修飾符合次數的特殊符號

前面章節講到的表達式,無論是只能符合一種字元的表達式,或是可以符合多種字符其中任意一個的表達式,都只能匹配一次。如果使用表達式再加上修飾符合次數的特殊符號,那麼不用重複書寫表達式就可以重複配對。

使用方法是:"次數修飾"放在"被修飾的表達式"後邊。例如:"[bcd][bcd]" 可以寫成 "[bcd]{2}"。

表達式

#作用

{n}

表達式重複n次,例如:"/w{2}" 相當於"/w/w";"a{5}" 相當於"aaaaa "

{m,n}

#表達式至少重複m次,最多重複n次,例如: "ba{1,3}"可以符合"ba"或"baa"或"baaa"

#{m,}

表達式至少重複m次,例如:"/w/d{2,}"可以符合"a12","_456","M12344"...

#?

匹配表達式0次或1次,相當於{0,1},例如:"a[cd]?"可以符合" a","ac","ad"

表達式至少出現1次,相當於{ 1,},例如:"a b"可以匹配"ab","aab","aaab"...

*

表達式不出現或出現任意次,相當於{0,},例如:"/^*b"可以匹配"b","^^^b"...

範例1:表達式"/d /.?/d*" 在符合"It costs $12.5" 時,配對的結果是:成功;符合的內容是: "12.5";配對到的位置是:開始於10,結束於14。 範例2:表達式"go{2,8}gle" 在匹配"Ads by goooooogle" 時,匹配的結果是:成功;匹配到的內容是:"goooooogle";匹配到的位置是:開始於7,結束於17。 ##有些符號在表達式中代表抽象的特殊意義:表達式作用#^與字串開始的地方匹配,不匹配任何字元#$/b

1.6 其他一些代表抽象意義的特殊符號

##與字串結束的地方匹配,不匹配任何字元

######匹配一個單字邊界,也就是單字和空格之間的位置,不符合任何字元################

進一步的文字說明仍然比較抽象,因此,舉例幫助大家理解。

範例1:表達式 "^aaa" 在符合 "xxx aaa xxx" 時,匹配結果是:失敗。因為 "^" 要求與字串開始的地方匹配,因此,只有當 "aaa" 位於字串的開頭的時候,"^aaa" 才能匹配,例如:"aaa xxx xxx"。

範例2:表達式 "aaa$" 在符合 "xxx aaa xxx" 時,匹配結果是:失敗。因為 "$" 要求與字串結束的地方匹配,因此,只有當 "aaa" 位於字串的結尾的時候,"aaa$" 才能匹配,例如:"xxx xxx aaa"。

範例3:表達式"./b." 在匹配"@@@abc" 時,匹配結果是:成功;匹配到的內容是:"@a";匹配到的位置是:開始於2,結束於4。
進一步說明:"/b" 與"^" 和"$" 類似,本身不匹配任何字符,但是它要求它在匹配結果中所處位置的左右兩邊,其中一邊是"/w" 範圍,另一邊是非"/w" 的範圍。

範例4:表達式"/bend/b" 在匹配"weekend,endfor,end" 時,匹配結果是:成功;匹配到的內容是:"end";匹配到的位置是:開始於15,結束於18。

一些符號可以影響表達式內部的子表達式之間的關係:

##|左右兩邊表達式之間"或" 關係,匹配左邊或右邊( )

表達式

作用

#|


(1). 在被修飾匹配次數的時候,括號中的表達式可以作為整體被修飾

(2). 取匹配結果的時候,括號中的表達式匹配到的內容可以被單獨得到

#舉例5:表達式"Tom|Jack " 在匹配字串"I'm Tom, he is Jack" 時,匹配結果是:成功;匹配到的內容是:"Tom";匹配到的位置是:開始於4,結束於7。匹配下一個時,匹配結果是:成功;匹配到的內容是:"Jack";匹配到的位置時:開始於15,結束於19。 範例6:表達式"(go/s*) " 在匹配"Let's go go go!" 時,匹配結果是:成功;匹配到內容是:"go go go";匹配到的位置是:開始於6,結束於14。

範例7:表達式"¥(/d /.?/d*)" 在配對"$10.9,¥20.5" 時,配對的結果是:成功;符合的內容是:"¥ 20.5";配對到的位置是:開始於6,結束於10。單獨取得括號範圍所符合的內容是:"20.5"。

2. 正規表示式中的一些高階規則

在使用修飾匹配次數的特殊符號時,有幾種表示方法可以使同一個表達式能夠匹配不同的次數,例如:"{m,n}", "{m,}", " ?", "*", " ",具體符合的次數隨被符合的字串而定。這種重複匹配不定次數的表達式在匹配過程中,總是盡可能多的匹配。例如,針對文字"dxxxdxxxd",舉例如下:#表達式符合結果(d)(/w )"/w " 將符合第一個"d" 之後的所有字元"xxxdxxxd "(d)(/w )(d)
#2.1 符合次數中的貪婪與非貪婪

#########"/w " 將會符合第一個"d" 和最後一個"d" 之間的所有字元"xxxdxxx"。雖然"/w " 也能夠匹配上最後一個"d",但是為了使整個表達式匹配成功,"/w " 可以"讓出" 它本來能夠匹配的最後一個"d"####### ########

由此可見,"/w " 在匹配的時候,總是盡可能多的匹配符合它規則的字元。雖然第二個舉例中,它沒有符合最後一個 "d",但那也是為了讓整個表達式能夠匹配成功。同理,帶有 "*" 和 "{m,n}" 的表達式都是盡可能地多匹配,帶 "?" 的表達式在可匹配可不匹配的時候,也是盡可能的 "要匹配"。這 種配對原則就叫作 "貪婪" 模式 。

非貪婪模式:

在修飾符合次數的特殊符號後再加上一個"?" 號,則可以使符合次數不定的表達式盡可能少的匹配,使可匹配可不匹配的表達式,盡可能的"不匹配"。這種匹配原則叫作 "非貪婪" 模式,也叫作 "勉強" 模式。如果少匹配就會導致整個表達式匹配失敗的時候,與貪婪模式類似,非貪婪模式會最小限度的再匹配一些,以使整個表達式匹配成功。舉例如下,針對文字"dxxxdxxxd" 舉例:

##(d)(/w ?)

#表達式

#########"/w ?" 將盡可能少的匹配第一個"d" 之後的字符,結果是:"/w ?" 只匹配了一個"x"###################(d)(/w ?)(d)### #########為了讓整個表達式匹配成功,"/w ?" 不得不匹配"xxx" 才可以讓後邊的"d" 匹配,從而使整個表達式匹配成功。因此,結果是:"/w ?" 匹配 "xxx"#​​###############

更多的情況,舉例如下:

舉例1:表達式"(.*)" 與字串"

aa< ;/p>

bb

" 匹配時,匹配的結果是:成功;匹配到的內容是"< p>aa

bb

" 整個字串,表達式中的"" 將與字串中最後一個"" 匹配。

舉例2:相較之下,表達式"(.*?)" 匹配舉例1中同樣的字串時,將只得到"

aa

", 再次配對下一個時,可以得到第二個"

bb

"。

2.2 反向引用/1, /2...

表達式在符合時,表達式引擎會將小括號"( )" 包含的表達式式所匹配到的字串記錄下來。在取得符合結果的時候,小括號包含的表達式所符合的字串可以單獨取得。這一點,在前面的舉例中,已經多次展示了。在實際應用場合中,當用某種邊界來查找,而所要取得的內容又不包含邊界時,必須使用小括號來指定所要的範圍。例如前面的 "(.*?)"。

其實,"小括號包含的表達式所匹配到的字串" 不僅是在匹配結束後才可以使用,在匹配過程中也可以使用。表達式後邊的部分,可以引用前面 "括號內的子符合已經符合的字串"。引用方法是 "/" 加上一個數字。 "/1" 引用第1對括號內匹配到的字串,"/2" 引用第2對括號內匹配到的字串…以此類推,如果一對括號內包含另一對括號,則外層的括號先排序號。換句話說,哪一對的左括號"(" 在前,那這一對就先排序號。

舉例如下:

舉例1:表達式"('|" )(.*?)(/1)" 在匹配" 'Hello', "World" " 時,匹配結果是:成功;匹配到的內容是:" 'Hello' "。再次匹配下一個時,可以匹配到" "World" "。

範例2:表達式"(/w)/1{4,}" 在匹配"aa bbbb abcdefg ccccc 111121111 999999999" 時,匹配結果是:成功;匹配到的內容是"ccccc"。再次符合下一個時,將得到999999999。這個表達式要求"/w" 範圍的字元至少重複5次,注意與"/w{5,}" 之間的區別。

範例3:表達式"<(/w )/s*(/w (=('|").*?/4)?/s*)*>.*?" 在匹配"" 時,匹配結果是成功。如果"" 與" " 不配對,則會匹配失敗;如果改成其他配對,也可以匹配成功。

2.3 預搜索,不匹配;反向預搜索,不匹配

前面的章節中,我講到了幾個代表抽象意義的特殊符號:"^","$","/b"。它們都有一個共同點,那就是:它們本身不匹配任何字符,只是對"字串的兩頭" 或"字元之間的縫隙" 附加了一個條件。理解到這個概念以後,本節將繼續介紹另外一種對"兩頭" 或"縫隙" 附加條件的,更加靈活的表示方法。

正向預先搜尋:"(?=xxxxx)","(?!xxxxx)"

格式:"(?=xxxxx)",在已符合的字串中,它對所處的"縫隙" 或"兩頭" 附加的條件是:所在縫隙的右側,必須能夠匹配上xxxxx 這部分的表達式。因為它只是在此作為這個縫隙上附加的條件,所以它不會影響後邊的表達式去真正匹配這個縫隙之後的字符。這就類似"/b",本身不匹配任何字符。"/b" 只是將所在縫隙之前、之後的字符取來進行了一下判斷,不會影響後邊的表達式來真正的匹配。

舉例1:表達式"Windows (?=NT|XP)" 在匹配"Windows 98, Windows NT, Windows 2000" 時,將只符合"Windows NT" 中的"Windows ",其他的"Windows " 字樣則不被符合。

範例2:表達式"(/w)((?=/1/1/1)(/1)) " 在符合字串"aaa ffffff 999999999" 時,將可以符合6個"f"的前4個,可以搭配9個"9"的前7個。這個表達式可以讀解成:重複4次以上的字母數字,則符合其剩下最後2位元之前的部分。當然,這個表達式可以不這樣寫,在此的目的是作為演示之用。

格式:"(?!xxxxx)",所在縫隙的右側,必須不能符合 xxxxx 這部分錶達式。

範例3:表達式"((?!/bstop/b).) " 在匹配"fdjka ljfdl stop fjdsla fdj" 時,將從頭一直匹配到"stop" 之前的位置,如果字串中沒有"stop",則符合整個字串。

範例4:表達式 "do(?!/w)" 在符合字串 "done, do, dog" 時,只能符合 "do"。在本條舉例中,"do" 後邊使用 "(?!/w)" 和使用 "/b" 效果是一樣的。

反向預先搜尋:"(?<=xxxxx)","(?

這兩種格式的概念和正向預搜尋是類似的,反向預搜尋要求的條件是:所在縫隙的"左側",兩種格式分別要求必須能夠匹配和必須不能夠匹配指定表達式,而不是去判斷右側。與 "正向預搜尋" 一樣的是:它們都是對所在縫隙的一種附加條件,本身都不符合任何字元。

範例5:表達式"(?<=/d{4})/d (?=/d{4})" 在符合"1234567890123456" 時,將符合除了前4個數字和後4個數字之外的中間8個數字。由於 JScript.RegExp 不支援反向預搜索,因此,本條舉例無法進行示範。許多其他的引擎可以支援反向預搜索,例如:Java 1.4 以上的 java.util.regex 包,.NET 中System.Text.RegularExpressions 命名空間,以及本站推薦的最簡單易用的 DEELX 正則引擎。

3. 其他通用規則

還有一些在各個正規表示式引擎之間比較通用的規則,在前面的講解過程中沒有提到。

3.1 表達式中,可以使用"/xXX" 和"/uXXXX" 表示一個字元("X" 表示一個十六進位數)

形式

字元範圍

/xXX

#編號在0 ~ 255 範圍的字符,例如:空格可以使用"/x20" 表示

/uXXXX

任何字元可以使用"/u" 再加上其編號的4位十六進位數表示,例如:"/中"

#3.2 在表達式"/s","/d","/w","/b" 表示特殊意義的同時,對應的大寫字母表示相反的意義

表達式

#可符合

/S

符合所有非空白字元("/s" 可符合各個空白字元)

/D

符合所有的非數字字元

/W

符合所有的字母、數字、底線以外的字元

/B

#符合非單字邊界,即左右兩邊都是"/w"範圍或左右兩邊都不是"/w" 範圍時的字元縫隙

#

3.3 在表達式中有特殊意義,需要添加"/" 才能匹配該字元本身的字元匯總

## 修飾符合次數為0 次或1次。若要符合"?" 字元本身,請使用"/?"修飾符合次數為至少1次。要匹配" " 字元本身,請使用"/ "*修飾匹配次數為0 次或任意次。要符合"*" 字元本身,請使用"/*"#|左右兩邊表達式之間"或" 關係。匹配"|" 本身,請使用"/|"

字元

說明

^

#符合輸入字串的開始位置。要匹配"^" 字元本身,請使用"/^"

#$

##來匹配輸入字串的結尾位置。要匹配"$" 字元本身,請使用"/$"

#( )

標記一個子表達式的開始和結束位置。要符合小括號,請使用"/(" 和"/)"

#[ ]

來自定義能夠匹配'多種字元' 的表達式。若要匹配中括號,請使用"/[" 和"/]"

#{ }

修飾匹配次數的符號。若要符合大括號,請使用"/{" 和"/}"

#.

「換行符(/n)以外的任一個字元。要符合小數點本身,請使用"/."

#?

#3.4 括號"( )" 內的子表達式,如果希望匹配結果不進行記錄供以後使用,可以使用"(?:xxxxx)" 格式

舉例1:表達式"(?:(/w)/1) " 匹配"a bbccdd efg" 時,結果是"bbccdd"。括號 "(?:)" 範圍的符合結果不進行記錄,因此 "(/w)" 使用 "/1" 來引用。

3.5 常用的表達式屬性設定簡介:Ignorecase,Singleline,Multiline,Global

##說明Ignorecase預設情況下,表達式中的字母是要區分大小寫的。配置為 Ignorecase 可使匹配時不區分大小寫。有的表達式引擎,把 "大小寫" 概念延伸到 UNICODE 範圍的大小寫。 Singleline#預設情況下,小數點"." 符合除了換行符號(/n)以外的字符。配置為 Singleline 可使小數點可符合包括換行符號在內的所有字元。 Multiline#預設情況下,表達式"^" 和"$" 只符合字串的開始① 和結尾④ 位置。如:Global#主要在將表達式用來替換時起作用,配置為Global 表示取代所有的匹配。 #

4. 其他提示

4.1 如果想要了解進階的正規引擎也支援那些複雜的正規語法,可參考本站DEELX 正規引擎的說明文檔。

4.2 如果要要求表達式所符合的內容是整個字串,而不是從字串中找一部分,那麼可以在表達式的首尾使用"^" 和"$",例如:"^ /d $" 要求整個字串只有數字。

4.3 如果要求匹配的內容是一個完整的單詞,而不會是單字的一部分,那麼在表達式首尾使用"/b",例如:使用"/b(if|while|else| void|int……)/b" 來符合程式中的關鍵字。

4.4 表達式不要符合空字串。否則會一直得到配對成功,而結果什麼都沒有匹配到。例如:準備寫一個符合"123"、"123."、"123.5"、".5" 這幾種形式的表達式時,整數、小數點、小數數字都可以省略,但是不要將表達式寫成:" /d*/.?/d*",因為如果什麼都沒有,這個表達式也可以匹配成功。更好的寫法是:"/d /.?/d*|/./d "。

4.5 能符合空字串的子符合不要循環無限次。如果括號內的子表達式中的每一部分都可以匹配 0 次,而這個括號整體又可以匹配無限次,那麼情況可能比上一條所說的更嚴重,匹配過程中可能死循環。雖然現在有些正規表示式引擎已經透過辦法避免了這種情況出現死循環了,例如 .NET 的正規表示式,但我們還是應該盡量避免這種情況。如果我們在寫表達式時遇到了死循環,也可以從這一點入手,找出是否是本條所說的原因。

4.6 合理選擇貪婪模式與非貪婪模式,參見主題討論。

4.7 或 "|" 的左右兩邊,對某個字元最好只有一邊可以匹配,這樣,不會因為 "|" 兩邊的表達式因為交換位置而有所不同。

下一篇----------------------------------- -----------

1,定義正規表示式

1)定義正規表示式有兩種形式,一種是普通方式,一種是建構函數方式。

2)普通方式:var reg=/表達式/附加參數

表達式:一個字串,代表了某種規則,其中可以使用某些特殊字符,來代表特殊的規則,後面會詳細說明。

附加參數:用來擴展表達式的意義,目前主要有三個參數:
g:代表可以進行全域匹配。
i:代表不區分大小寫匹配。
m:代表可以進行多行比對。

上面三個參數,可以任意組合,代表複合意義,當然也可以不加參數。

範例:
var reg=/a*b/;
var reg=/abc f/g;

3)建構子方式:var reg=new RegExp( “表達式”,”附加參數”);
其中“表達式”與“附加參數”的含義與上面那種定義方式中的含義相同。
範例:
var reg=new RegExp(“a*b”);
var reg=new RegExp(“abc f”,”g”);

4)普通方式與建構函數方式的區別
普通方式中的表達式必須是一個常數字串,而建構函數中的表達式可以是常數字串,也可以是一個js變量,例如根據使用者的輸入來作為表達式參數等等:
var reg=new RegExp(document.forms[0].exprfiled.value,”g”);

##2,表達式模式

1)表達式模式,是指表達式的表達式與樣式,即var reg=/表達式/附加參數中的「表達式」怎樣去描述?

2)從規範上講,表達式模式分為簡單模式和複合模式。
3)簡單模式:是指透過普通字元的組合來表達的模式,例如
var reg=/abc0d/;
可見簡單模式只能表示具體的匹配。

4)複合模式:是指含有通配符來表達的模式,例如:

var reg=/a b?/w/;
其中的、?和/w都屬於通配符,代表著特殊的意義。因此複合模式可以表達出更抽象化的邏輯。
下面我們著重說複合模式中各個通配符的意義及其使用。

5)複合模式中特殊字元的講解:

1>/:在許多程式語言裡面被用來當作轉義符,一般來說

/符號後面如果跟的是普通字元c,那麼/c就代表特殊的意義,例如n本來代表字元n,但/n就代表換行。
/符號後面如果跟的是特殊字元c,那麼/c就代表普通字元c,例如/一般用作轉義符,但//則調表普通字元/。
Javascript的正規表示式中/的用法與上面相同,只是不同的程式語言,特殊字元表可能不太一樣罷了。

2>^:匹配输入字符串的起始端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符后匹配。
例子:
/^B/匹配 “Bab Bc ”中的第一个B

例子2:
/^B/gm匹配
“Badd B
cdaf
B dsfB”

中的第一行第一个B,第三行中的第一个B

3>$:匹配输入字符创的尾端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符前匹配。

与^的用法相反。

例子:/t$/匹配“bat”中的t,但是不匹配“hate”中的t

例子2:/t$/匹配

“tag at
bat”
中第一行的最后一个t和第二行的t。

4>*:匹配前一个字符0次或多次。

例子:/ab*/匹配“dddabbbbc”中的“abbbb”,也匹配“ddda”中的“a”

5>+:匹配前一个字符1次或多次。

例子:/ab+/匹配“dddabbbbc”中的“abbbb”,但不匹配“ddda”

与后面的{1,}(原型:{n,})的用法类似

6>?:?的用法比较特殊,一般来说它用来对前一个字符做0次或1次匹配,但是它有另外两种特殊的用法:

如果紧跟在*、+、?和{ }之后,则表示原始匹配的最小次数匹配,例如:
/ba*/本来匹配“bbbaaaa”中的“baaaa”,但是/ba*?/则匹配“bbbaaaa”中的“b”(因为*表示0次或多次匹配,而加?应该表示最少次数匹配,即0次匹配)。
同理:/ba+?/则匹配“baaaa”中的“ba”。
作为语法结构符号,使用于前置断言中,即后面要说到的x(?=y)和x(?!=y)

7>.:小数点中的“.”号,匹配任何一个单独的字符,但是换行符除外。

标准中总共有哪些字符?请参考:字符集
例如:/a.b/匹配“acbaa”中的“acb”,但是不匹配“abbb”。

8>(x):表示匹配x(并非特指字符x或者特指一个字符,x表示一个字符串),而且匹配会被记住,在语法中这种()被称为“capturing parentheses ”,即捕捉用的小括号。

匹配会被记住,是因为在表达式提供的函数中,有些函数返回一个数组,该数组会保存所匹配的所有字符串,例如exec()函数。
另外还要注意()中的x被记住的前提是匹配x。

例子1:

var regx=/a(b)c/;
var rs=regx.exec(“abcddd”);
登入後複製

从上面可以看出,/a(b)c/匹配“abcddd”中的“abc”,因为()的原因,b也会记录下来,因此rs返回的数字内容为:
{abc,b}

例子2:

var regx=/a(b)c/;
var rs=regx.exec(“acbcddd”);
登入後複製

rs返回null,因为/a(b)c/不匹配“acbcddd”,所以()中的b不会被记录下来(尽管字符串中含有b)

9>(?:x):匹配x,但不会记住x,这种格式中的()被称为“non-capturing parentheses ”,即非捕捉用的小括号。

例子:

var regx=/a(?:b)c/;
var rs=regx.exec(“abcddd”);
登入後複製

从上面可以看出,/a(?:b)c/匹配“abcddd”中的“abc”,因为(?:)的原因,b不会记录下来,因此rs返回的数字内容为:
{abc}

10>X(?=y):匹配x,仅当后面紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。

例子:

var regx=/user(?=name)/;
var rs=regx.exec(“The username is Mary”);
登入後複製

结果:匹配成功,而且rs的值为{user}

11>X(?!y):匹配x,仅当后面不紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。

例子:

var regx=/user(?!name)/;
var rs=regx.exec(“The user name is Mary”);
登入後複製

结果:匹配成功,而且rs的值为{user}

例子2:

var regx=//d+(?!/.)/;
var rs=regx.exec(“54.235”);
登入後複製

结果:匹配成果,rs的值为{5},不匹配54是因为54后面跟着“.”号,当然235也匹配,但是由于exec方法的行为,235不会被返回

12>x|y:匹配x或y。注意如果x和y都匹配上了,那么只记住x。

例子:

var regx=/beijing|shanghai/;
var rs=regx.exec(“I love beijing and shanghai”);
登入後複製

结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。

13>{n}:匹配前一个字符的n次出现。
n必须是一个非负数,当然如果是一个负数或小数也不会报语法错误。

例子:

var regx=/ab{2}c/;
var rs=regx.exec(“abbcd”);
登入後複製

结果:匹配成功,rs的值为:{abbc}。

14>{n,}:匹配前一个字符的至少n次出现。

例子:

var regx=/ab{2,}c/;
var rs=regx.exec(“abbcdabbbc”);
登入後複製

结果:匹配成功,rs的值为:{abbc}。注意为什么abbbc也符合条件为什么没有被记住,这与exec方法的行为有关,后面会统一讲解。

15>{n,m}:匹配前一个字符的至少n次最多m次的出现。
只要n与m为数字,而且m>=n就不会报语法错误。

例子:

var regx=/ab{2,5}c/;
var rs=regx.exec(“abbbcd”);
登入後複製

结果:匹配成功,rs的值为:{abbbc}。

例子2:

var regx=/ab{2,2}c/;
var rs=regx.exec(“abbcd”);
登入後複製

结果:匹配成功,rs的值为:{abbc}。

例子3:

var regx=/ab(2,5)/;
var rs=regx.exec(“abbbbbbbbbb”);
登入後複製

结果:匹配成功,rs的值为:{abbbbb},这说明,如果前一个字符出现多于m次,则只匹配m次。另外:
var regx=/ab(2,5)c/;
var rs=regx.exec(“abbbbbbbbbbc”);
结果:匹配失败,rs的值为:null,为什么匹配失败,因为b多于5个则b(2,5)会匹配前5个b,,而表达式/ab(2,5)c/中b后面是c,但字符串中5个b之后还是b所以会报错。

16>[xyz]:xyz表示一个字符串,该模式表示匹配[]中的一个字符,形式上[xyz]等同于[x-z]。

例子:

var regx=/a[bc]d/;
var rs=regx.exec(“abddgg”);
登入後複製

结果:匹配成功,rs的值为:{abd}

例子2:

var regx=/a[bc]d/;
var rs=regx.exec(“abcd”);
登入後複製

结果:匹配失败,rs的值为:null,之所以失败,是因为[bc]表示匹配b或c中的一个,但不会同时匹配。

17>[^xyz]:该模式表示匹配非[]中的一个字符,形式上[^xyz]等同于[^x-z]。

例子:

var regx=/a[^bc]d/;
var rs=regx.exec(“afddgg”);
登入後複製

结果:匹配成功,rs的值为:{afd}

例子2:

var regx=/a[^bc]d/;
var rs=regx.exec(“abd”);
登入後複製

结果:匹配失败,rs的值为:。

18>[/b]:匹配退格键。

19>/b:匹配一个词的边界符,例如空格和换行符等等,当然匹配换行符时,表达式应该附加参数m。

例子:

var regx=//bc./;
var rs=regx.exec(“Beijing is a beautiful city”);
登入後複製

结果:匹配成功,rs的值为:{ci},注意c前边的空格不会匹配到结果中,即{ ci}是不正确的。

20>/B:代表一个非单词边界。

例子:

var regx=//Bi./;
var rs=regx.exec(“Beijing is a beautiful city”);
登入後複製

结果:匹配成功,rs的值为:{ij},即匹配了Beijing中的ij。

21>/cX,匹配一个控制字符。例如, /cM 匹配一个 Control-M 或
回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一
个原义的 'c' 字符。(实际的例子还需补充)

21>/d:匹配一个数字字符,等同于[0-9]。

例子:

var regx=/user/d/;
var rs=regx.exec(“user1”);
登入後複製

结果:匹配成功,rs的值为:{user1}

22>/D:匹配一个非数字字符,等同于[^0-9]。
例子:

var regx=/user/D/;
var rs=regx.exec(“userA”);
登入後複製

结果:匹配成功,rs的值为:{userA}

23>/f:匹配一个换页符。

24>/n:匹配一个换行符。因为是换行符,所以在表达式中要加入m参数。
例子:

var regx=/a/nbc/m;
 var str=“a
 bc”;
var rs=regx.exec(str);
登入後複製

结果:匹配成功,rs的值为:{ },如果表达式为/a/n/rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。
25>/r:匹配一个回车符

26>/s:匹配一个空格符,等同于[ /f/n/r/t/v/u00A0/u2028/u2029].

例子:

var regx=//si/;
var rs=regx.exec(“Beijing is a city”);
登入後複製

结果:匹配成功,rs的值为:{ i}

27>/S:匹配一个非空格符,等同于[ ^/f/n/r/t/v/u00A0/u2028/u2029].

例子:

var regx=//Si/;
var rs=regx.exec(“Beijing is a city”);
登入後複製

结果:匹配成功,rs的值为:{ei}

28>/t:匹配一个tab

例子:

var regx=/a/tb/;
var rs=regx.exec(“a bc”);
登入後複製

结果:匹配成功,rs的值为: {a bc}

29>/v:匹配一个竖向的tab

30>/w:匹配一个数字、_或字母表字符,即[A-Za-z0-9_ ]。

例子:

var regx=//w/;
var rs=regx.exec(“$25.23”);
登入後複製
登入後複製

结果:匹配成功,rs的值为:{2}

31>/W:匹配一个非数字、_或字母表字符,即[^A-Za-z0-9_ ]。

例子:

var regx=//w/;
var rs=regx.exec(“$25.23”);
登入後複製
登入後複製

结果:匹配成功,rs的值为:{$}

32>/n:注意不是/n,这里n是一个正整数,表示匹配第n个()中的字符。

例子:

var regx=/user([,-])group/1role/;
var rs=regx.exec(“user-group-role”);
登入後複製

结果:匹配成功,rs的值为:{user-group-role,-},同样对user,group,role的匹配也是成功的,但像user-group,role等就不对了。

33>/0:匹配一个NUL字符。

34>/xhh:匹配一个由两位16进制数字所表达的字符。

35>/uhhhh:匹配一个由四位16进制数字所表达的字符。

3,表达式操作

1)表达式操作,在这里是指和表达式相关的方法,我们将介绍六个方法。
2)表达式对象(RegExp)方法:

1>exec(str),返回str中与表达式相匹配的第一个字符串,而且以数组的形式表现,当然如果表达式中含有捕捉用的小括号,则返回的数组中也可能含有()中的匹配字符串,例如:

var regx=//d+/;
var rs=regx.exec(“3432ddf53”);
登入後複製

返回的rs值为:{3432}

var regx2=new RegExp(“ab(/d+)c”);
var rs2=regx2.exec(“ab234c44”);
登入後複製

返回的rs值为:{ab234c,234}
另外,如果有多个合适的匹配,则第一次执行exec返回一个第一个匹配,此时继续执行exec,则依次返回第二个第三个匹配。例如:

var regx=/user/d/g;
var rs=regx.exec(“ddduser1dsfuser2dd”);
var rs1=regx.exec(“ddduser1dsfuser2dd”);
登入後複製

则rs的值为{user1},rs的值为{rs2},当然注意regx中的g参数是必须的,否则无论exec执行多少次,都返回第一个匹配。后面还有相关内容涉及到对此想象的解释。

2>test(str),判断字符串str是否匹配表达式,返回一个布尔值。例如:

var regx=/user/d+/g;
var flag=regx.test(“user12dd”);
登入後複製

flag的值为true。

3)String对象方法

1>match(expr),返回与expr相匹配的一个字符串数组,如果没有加参数g,则返回第一个匹配,加入参数g则返回所有的匹配
例子:

var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.match(regx);
登入後複製

rs的值为:{user1,user3}

2>search(expr),返回字符串中与expr相匹配的第一个匹配的index值。
例子:

var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.search(regx);
登入後複製

rs的值为:0

3>replace(expr,str),将字符串中匹配expr的部分替换为str。另外在replace方法中,str中可以含有一种变量符号$,格式为$n,代表匹配中被记住的第n的匹配字符串(注意小括号可以记忆匹配)。
例子:

var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
登入後複製

rs的值为:003userddd0045
例子2:

var regx=/u(se)r/d/g;
var str=“user13userddduser345”;
var rs=str.replace(regx,”$1”);
登入後複製

rs的值为:se3userdddse45
对于replace(expr,str)方法还要特别注意一点,如果expr是一个表达式对象则会进行全局替换(此时表达式必须附加参数g,否则也只是替换第一个匹配),如果expr是一个字符串对象,则只会替换第一个匹配的部分,例如:

var regx=“user”
var str=“user13userddduser345”;
var rs=str.replace(regx,”00”);
登入後複製

rs的值为: 0013userddduser345

4>split(expr),将字符串以匹配expr的部分做分割,返回一个数组,而且表达式是否附加参数g都没有关系,结果是一样的。
例子:

var regx=/user/d/g;
var str=“user13userddduser345”;
var rs=str.split(regx);
登入後複製

rs的值为:{3userddd,45}

4,表达式相关属性

1)表达式相关属性,是指和表达式相关的属性,如下面的形式:

var regx=/myexpr/;
var rs=regx.exec(str);
登入後複製

其中,和表达式自身regx相关的属性有两个,和表达式匹配结果rs相关的属性有三个,下面将逐一介绍。
2)和表达式自身相关的两个属性:

1>lastIndex,返回开始下一个匹配的位置,注意必须是全局匹配(表达式中带有g参数)时,lastIndex才会有不断返回下一个匹配值,否则该值为总是返回第一个下一个匹配位置,例如:

var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex1=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex2=regx.lastIndex;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var lastIndex3=regx.lastIndex;
登入後複製

上面lastIndex1为9,第二个lastIndex2也为9,第三个也是9;如果regx=/user/d/g,则第一个为9,第二个为18,第三个为0。

2>source,返回表达式字符串自身。例如:

var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var source=regx.source;
登入後複製

source的值为user/d
3)和匹配结果相关的三个属性:

1>index,返回当前匹配的位置。例如:

var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var index1=rs.index;
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index2=rs.index; 
rs=regx.exec(“sdsfuser1dfsfuser2”);
var index3=rs.index;
登入後複製

index1为4,index2为4,index3为4,如果表达式加入参数g,则index1为4,index2为13,index3会报错(index为空或不是对象)。

2>input,用于匹配的字符串。例如:

var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var input=rs.input;
登入後複製

input的值为sdsfuser1dfsfuser2。

3>[0],返回匹配结果中的第一个匹配值,对于match而言可能返回一个多值的数字,则除了[0]外,还可以取[1]、[2]等等。例如:

var regx=/user/d/;
var rs=regx.exec(“sdsfuser1dfsfuser2”);
var value1=rs[0];
rs=regx.exec(“sdsfuser1dfsfuser2”);
var value2=rs[0];
登入後複製

value1的值为user1,value2的值为user2

5,实际应用

1)实际应用一
描述:有一表单,其中有一个“用户名”input域
要求:汉字,而且不能少于2个汉字,不能多于4个汉字。
实现:

<script>
function checkForm(obj){
   var username=obj.username.value;
   var regx=/^[/u4e00-/u9fa5]{2,4}$/g
   if(!regx.test(username)){
        alert(“Invalid username!”);
        return false; 
   }
   return true;
}
</script>
<form name=“myForm”onSubmit=“return checkForm(this)”>
  <input type=“text” name=“username”/>
  <input type=“submit” vlaue=“submit”/>
</form>
登入後複製

2)实际应用二

描述:给定一个含有html标记的字符串,要求将其中的html标记去掉。

实现:

<script>
function toPlainText(htmlStr){
   var regx=/<[^>]*>|<//[^>]*>/gm;
   var str=htmlStr.replace(regx,"");
   return str;
}
</script>
<form name=“myForm”>
  <textarea id=“htmlInput”></textarea>
  <input type=“button” value=“submit” onclick=“toPlainText(document.getElementById(‘htmlInput&#39;).value”/>
</form>
登入後複製

三,小结

1,Javascript正则表达式,我想在一般的程序员之中,使用者应该不是很多,因为我们处理的页面一般都不是很复杂,而复杂的逻辑一般我们都在后台处理完成了。但是目前趋势已经出现了扭转,富客户端已经被越来越多的人接受,而Javascript就是其中的关键技术,对于复杂的客户端逻辑而言,正则表达式的作用也是很关键的,同时它也是Javascript高手必须要掌握的重要技术之一。

2,为了能够便于大家对前面讲述的内容有一个更为综合和深刻的认识,我将前面的一些关键点和容易犯糊涂的地方再系统总结一下,这部分很关键!

总结1:附件参数g的用法

表达式加上参数g之后,表明可以进行全局匹配,注意这里“可以”的含义。我们详细叙述:

1)对于表达式对象的exec方法,不加入g,则只返回第一个匹配,无论执行多少次均是如此,如果加入g,则第一次执行也返回第一个匹配,再执行返回第二个匹配,依次类推。例如

var regx=/user/d/;
var str=“user18dsdfuser2dsfsd”;
var rs=regx.exec(str);//此时rs的值为{user1}
var rs2=regx.exec(str);//此时rs的值依然为{user1}
登入後複製

如果regx=/user/d/g;则rs的值为{user1},rs2的值为{user2}

通过这个例子说明:对于exec方法,表达式加入了g,并不是说执行exec方法就可以返回所有的匹配,而是说加入了g之后,我可以通过某种方式得到所有的匹配,这里的“方式”对于exec而言,就是依次执行这个方法即可。

2)对于表达式对象的test方法,加入g于不加上g没有什么区别。

3)对于String对象的match方法,不加入g,也只是返回第一个匹配,一直执行match方法也总是返回第一个匹配,加入g,则一次返回所有的匹配(注意这与表达式对象的exec方法不同,对于exec而言,表达式即使加上了g,也不会一次返回所有的匹配)。例如:

var regx=/user/d/;
var str=“user1sdfsffuser2dfsdf”;
var rs=str.match(regx);//此时rs的值为{user1}
var rs2=str.match(regx);//此时rs的值依然为{user1}
登入後複製

如果regx=/user/d/g,则rs的值为{user1,user2},rs2的值也为{user1,user2}

4)对于String对象的replace方法,表达式不加入g,则只替换第一个匹配,如果加入g,则替换所有匹配。(开头的三道测试题能很好的说明这一点)

5)对于String对象的split方法,加上g与不加g是一样的,即:

var sep=/user/d/;
var array=“user1dfsfuser2dfsf”.split(sep);
登入後複製

则array的值为{dfsf, dfsf}

此时sep=/user/d/g,返回值是一样的。

6)对于String对象的search方法,加不加g也是一样的。

总结2:附加参数m的用法

附加参数m,表明可以进行多行匹配,但是这个只有当使用^和$模式时才会起作用,在其他的模式中,加不加入m都可以进行多行匹配(其实说多行的字符串也是一个普通字符串),我们举例说明这一点

1)使用^的例子

var regx=/^b./g;
var str=“bd76 dfsdf
     sdfsdfs dffs
     b76dsf sdfsdf”;
var rs=str.match(regx);
登入後複製

此时加入g和不加入g,都只返回第一个匹配{bd},如果regx=/^b./gm,则返回所有的匹配{bd,b7},注意如果regx=/^b./m,则也只返回第一个匹配。所以,加入m表明可以进行多行匹配,加入g表明可以进行全局匹配,综合到一起就是可以进行多行全局匹配

2)使用其他模式的例子,例如

var regx=/user/d/;
var str=“sdfsfsdfsdf
     sdfsuser3 dffs
     b76dsf user6”;
var rs=str.match(regx);
登入後複製

此时不加参数g,则返回{user3},加入参数g返回{user3,user6},加不加入m对此没有影响。

3)因此对于m我们要清楚它的使用,记住它只对^和$模式起作用,在这两种模式中,m的作用为:如果不加入m,则只能在第一行进行匹配,如果加入m则可以在所有的行进行匹配。我们再看一个^的例子

var regx=/^b./;
var str=“ret76 dfsdf
     bjfsdfs dffs
     b76dsf sdfsdf”;
var rs=str.match(regx);
登入後複製

此时rs的值为null,如果加入g,rs的值仍然为null,如果加入m,则rs的值为{bj}(也就是说,在第一行没有找到匹配,因为有参数m,所以可以继续去下面的行去找是否有匹配),如果m和g都加上,则返回{bj,b7}(只加m不加g说明,可以去多行进行匹配,但是找到一个匹配后就返回,加入g表明将多行中所有的匹配返回,当然对于match方法是如此,对于exec呢,则需要执行多次才能依次返回)

总结3:

在HTML的textarea输入域中,按一个Enter键,对应的控制字符为“/r/n”,即“回车换行”,而不是“/n/r”,即“换行回车”,我们看一个前面我们举过的例子:

var regx=/a/r/nbc/;
var str=“a
     bc”;
var rs=regx.exec(str);
登入後複製

结果:匹配成功,rs的值为:{  },如果表达式为/a/n/rbc/,则不会被匹配,因此在一般的编辑器中一个”Enter”键代表着“回车换行”,而非“换行回车”,至少在textarea域中是这样的。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

关于js鼠标按键事件和键盘按键事件的使用方法

基于Vue-cli搭建的项目如何和后台交互的介绍

以上是關於JS正規表示式的RegExp物件和括號的使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板

     ①xxxxxxxxx②/n
#      ③xxxxxxxxx④

#      配置為 Multiline 可以使 "^" 匹配 ① 外,還可以匹配換行符之後,下一行開始前 ③ 的位置,使 "$" 匹配 ④ 外,還可以匹配換行符之前,一行結束 ② 的位置。