正則表達(dá)式淺略學(xué)習(xí)

在javascript編程中,會時常用到正則表達(dá)式。因此,決定對正則表達(dá)式進(jìn)行學(xué)習(xí)。

學(xué)習(xí)的目的主要是能夠在編程中使用到它,因此,不要求精通,只需對其基本知識有所了解即可。學(xué)習(xí)材料主要來自正則表達(dá)式30分鐘入門教程,作者deerchao。

從目錄及速覽全文后,我認(rèn)為,對正則表達(dá)式的基本了解應(yīng)該主要從字符、限定符、規(guī)則、語法這四方面進(jìn)行歸納。通過限定符和元字符配合使用來確定匹配字符的次數(shù),通過設(shè)定并遵守一些規(guī)則來達(dá)到更多的匹配方式,最后進(jìn)階使用語法來達(dá)到最高層的正則表達(dá)式匹配。

1.字符:正則表達(dá)式中的字符分為原意文本字符和元字符。確定的英文字母和數(shù)字在正則表達(dá)式中可以用其本身表示(愿意文本字符),而元字符是一些具有特殊意義的正則表達(dá)式特殊代碼,常用的元字符有下:

  • . 匹配除換行符以外的任意字符;
  • \w 匹配字母或數(shù)字或下劃線或漢字;
  • \s 匹配任意的空白符;
  • \d 匹配數(shù)字;
  • \b 匹配字符串開始或結(jié)束;
  • ^ 匹配字符串開始;
  • $ 匹配字符串的結(jié)束;

舉個例子,\b\d6\d\b表示的是匹配首字符為任意數(shù)字、中間字符為6、尾字符為任意數(shù)字的一個字符串,而\d6\d$同樣也是匹配的這樣一個字符串。由元字符會衍生出一個問題:元字符中有一些如.等是用特殊符號來表示的,那么在正則表達(dá)式中用什么來匹配它們自己呢?這就引出了轉(zhuǎn)義的規(guī)則:在這些特殊符號前面使用“\”對其進(jìn)行轉(zhuǎn)義,就可以匹配它們自身了。那么“\”又用什么來匹配呢?還是用它自己進(jìn)行轉(zhuǎn)義:正則表達(dá)式中的“\”就是用來匹配“\”的。

2.限定符:有了字符并不能解決問題,比如,如果想要匹配一個12位長的任意數(shù)字,難道要使用“\d”12次,那位數(shù)再多一些怎么辦呢?
于是限定符就起作用了。我的理解,限定符就是規(guī)定正則表達(dá)式中一個字符或一段字符要匹配的次數(shù),如下,是一些常用的限定符:

  • * 重復(fù)零次或更多次;
  • + 重復(fù)一次或更多次;
  • ? 重復(fù)零次或一次;
  • {n,} 重復(fù)n次或更多次;
  • {n,m} 重復(fù)n到m次;
  • {n} 重復(fù)n次;
  • *? 重復(fù)任意次,但盡可能少重復(fù);
  • +? 重復(fù)1次或更多次,但盡可能少重復(fù);
  • ?? 重復(fù)0次或1次,但盡可能少重復(fù);
  • {n,m}? 重復(fù)n到m次,但盡可能少重復(fù);
  • {n,}? 重復(fù)n次以上,但盡可能少重復(fù);

于是,要匹配12位長的數(shù)字,只需“\d{12}”這樣寫就行了。從上面可以明顯的看出,前五個和后五個以中間第六個為界限,可以歸納為兩大類,前五個叫做貪婪匹配,后五個叫做懶惰匹配(為什么用兩個貶義詞來定義,一臉懵逼??)。

3.規(guī)則:有了字符和限定符還并不能解決問題,還缺少一些規(guī)則,這些規(guī)則使我們能夠更便捷的使用正則表達(dá)式。比較常用的規(guī)則有:字符類、反義、分支條件、分組、和向后引用。以下一一解釋:

字符類:如果只想匹配某幾個確定的字母或數(shù)字,就需要使用到字符類。舉個例子,如果我只想匹配一段字符串中是否有a、b、c這三個字母,那么只需“[abc]”這樣表示就可以進(jìn)行匹配了,而這正是一個字符類。

反義:有時候,我們需要的結(jié)果是不想字符串中有某個字符或是某段字符(既匹配不含這些字符的字符串),就需要用到反義規(guī)則了,常見的反義規(guī)則代碼有下:

  • \W 匹配任意不是字母,數(shù)字,下劃線,漢字的字符;
  • \S 匹配任意不是空白符的字符;
  • \D 匹配任意非數(shù)字的字符;
  • \B 匹配不是單詞開頭或結(jié)束的位置;
  • [^x] 匹配除了x以外的任意字符;
  • [^aeiou] 匹配除了aeiou這幾個字母以外的任意字符;

分支條件:指的是有幾種匹配方式,如果滿足其中任意一種匹配方式都應(yīng)該當(dāng)成匹配。而分支條件的具體方法是把不同的匹配方式用|隔開。舉個例子,0\d{2}-\d{8}|0\d{3}-\d{7}這個正則表達(dá)式指的是只要某段字符串能夠滿足0xx-xxxxxxxx或者0xxx-xxxxxxx兩種形式中的任意一種(x代表數(shù)字),就可以被匹配。而分支條件需要遵守另外一條規(guī)則:正則表達(dá)式的匹配都是從左到右進(jìn)行匹配,如果字符串滿足了前面的匹配方式,就被前面匹配了,既使它(或者它內(nèi)部某段字符串,亦或它加上前后某段字符串)能夠滿足后面的匹配方式,也不會再次被后面匹配。

分組:分組的規(guī)則主要是為了滿足一些語法或是規(guī)則,具體方法是使用小括號將某段正則表達(dá)式包圍起來,既對其進(jìn)行了分組,在默認(rèn)情況下,如果一段正則表達(dá)式中有幾個組,那么他們的組號是從左至右從1開始依次增大的。\b(\w+)\d(\w+)\b這段正則表達(dá)式里,第一個(\w+)的組號為1,第二個(\w+)的組號為2。

而依賴分組規(guī)則,后向引用就起到了很大的作用。如:有這樣一段表達(dá)式,\b(\w+)\b\s+(\w+)\b,從中可見,第一個括號的內(nèi)容與第二個完全相同,此時,完全可以利用后項引用規(guī)則,用第一個組的組號來替代第二個組:\b(\w+)\b\s+\1\b。需要注意的是,利用組號來引用,一定要加上轉(zhuǎn)義符,如“\1”。

4.語法:常用的語法也主要依賴于分組,如下:

  • (exp) 匹配exp,并捕獲文本到自動命名的組里;
  • (?<name>exp) 匹配exp,并捕獲文本到名稱為name的組里,也可以寫成(?'name'exp);
  • (?:exp) 匹配exp,不捕獲匹配的文本,也不給此分組分配組號;
  • (?=exp) 匹配exp前面的位置;
  • (?<=exp) 匹配exp后面的位置;
  • (?!exp) 匹配后面跟的不是exp的位置;
  • (?<!exp) 匹配前面不是exp的位置;
  • (?#comment) 這種類型的分組不對正則表達(dá)式的處理產(chǎn)生任何影響,用于提供注釋讓人閱讀;

以上,前三個屬于捕獲,其后四個屬于零寬斷言,最后一個是注釋。需要注意的是零寬斷言,為什么叫零寬?因為它匹配的是一個位置,并不是字符;而斷言指的是這個位置需要滿足一定的條件。

以上就是正則表達(dá)式的大半基礎(chǔ)知識了,除此之外,還有處理選項、平衡組(遞歸匹配)等需要了解。對于一些常規(guī)的js編程如表單驗證等,利用上面的知識就足夠了。

但是,只利用正則表達(dá)式來匹配字符串并不能完全解決問題,比如有時需要計算字符串的字節(jié)長度,而字符串中含有漢字的情況下,需要將漢字進(jìn)行轉(zhuǎn)碼,形成unicode編碼,再對編碼用“\”來轉(zhuǎn)義,才能正確匹配找到漢字,并計算字節(jié)數(shù)。

Small Star's Blog|小星的博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容