正則表達式講解:
首先要知道正則表達式到底是幹什麼用的?
•測試字符串是否匹配格式:例如測試手機號郵箱是否符合規則
•替換文本內容:可以在一串文本中查找需要的內容進行批量替換
•根據匹配規則從文本中查找需要的內容:例如可以根據輸入選擇下拉框顯示內容;
總之正則表達式在web2.0時代顯得是那麼強勢流行,下面我們說說正則表達式如何構建
首先要了解RegExp對象,這是一個跟array一樣的普通對象;
用法:創建正則表達式只需要new RegExp()即可(現在對象裏面是空的 就是說創建了一個空的正則表達式 沒有任何功能);
var you=new RegExp("n",'i');
該構造函數內第一個參數是正則表達式要匹配的文本內容,第二個參數是表示不分大小,其中第二個參數可以接受三個值:
g(全文查找),i(不分大小寫),m(多行查找)或者組合使用,最多的使用是gi即全文查找並且不區分大小寫;
一般情況下我們書寫正則表達式都不會去new 一個RegExp對象 就像新建一個數組不會去new一個array一樣,而是用一種對象字面量形式來代替var you=/n/g;
正則表達式有哪些屬性或者方法?
方法:
•test, 返回一個 Boolean 值,它指出在被查找的字符串中是否存在模式。如果存在則返回 true,否則就返回 false。
舉例如下:you.test("nihao")//true
•exec, 該方法是專門爲捕獲組而設計的,接受一個參數,即要應用模式的字符串。然後返回包含第一個匹配項信息的數組,
或者在沒有匹配項情況下返回null,返回數組雖然是array的實例,但是包含兩個特殊屬性(index和input)
其中,index表示匹配項在字符串中的位置,而input表示應用正則表達式的字符串。在數組中,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串(如果存在)
舉例如下:
var text="abcdefade";
var a=/b(c(def)?)?/g;
var matchs=a.exec(text);
這個時候matchs爲["bcdef",'cdef','def'];
此時matchs.index爲1(第一個匹配的b爲字符串第二個位置)
補充:關於捕獲 下面會講到,如果不懂 可以看完捕獲後再回來看看該方法。
屬性:•source,返回正則表達式模式的文本的複本。只讀。
•lastIndex,返回字符位置,它是被查找字符串中下一次成功匹配的開始位置。
•$1...$9,返回九個在模式匹配期間找到的、最近保存的部分。只讀。
•input ($_),返回執行規範表述查找的字符串。只讀。
•lastMatch
($&),返回任何正則表達式搜索過程中的最後匹配的字符。只讀。
•lastParen
($+),如果有的話,返回任何正則表達式查找過程中最後括的子匹配。只讀。
•leftContext
($`),返回被查找的字符串中從字符串開始位置到最後匹配之前的位置之間的字符。只讀。
•rightContext ($'),返回被搜索的字符串中從最後一個匹配位置開始到字符串結尾之間的字符。只讀。
String對象一些和正則表達式相關的方法
•match,找到一個或多個正則表達式的匹配。舉例:var str="1 and 2 and 3"
alert(str.match(/\d+/g))//123
•replace,替換與正則表達式匹配的子串。
舉例:
var str="1 and 2 and 3"
alert(str.replace(/\d+/g,'n')//n and n and n
•search,檢索與正則表達式相匹配的index值。
舉例:
var str="1 and 2 and 3"
alert(str.search(/\d+/g)//0
•split,把字符串分割爲字符串數組。
舉例:
var str="1 and 2 and 3"
alert(str.split(/\d+/g)//[""," and "," and ",""](當匹配第一個或者最後一個字符時候會返回兩個空字符串);
以上這些都是正則表達式用法,到現在爲止 其實我們還沒有真正去了解正則表達式這門“語言”;
下面我們來真正走進這門語言:
--------------------------------------------------------------------------------------------------------------------------------------------
正則表達式語法詳解
如果你要在一個字符串中搜索有沒有at這個詞,你就可以用/at/g
但是有時候我們需要查找單獨的at而不是存在於cat類似中的at,那麼我們就需要用到元字符去查找了\bat/g;例如"cat at car".match(/\bat/g)就會返回["at"]而不包含cat
不幸的是,很多單詞裏包含hi這兩個連續的字符,比如him,history,high等等。用hi來查找的話,這裏邊的hi也會被找出來。如果要精確地查找hi這個單詞的話,我們應該使用\bhi\b。
剛纔我們說到了元字符,元字符是在正則表達式中有着舉足輕重的分量的。
表1.常用的元字符
代碼 | 說明 |
. | 匹配除換行符以外的任意字符 |
\w | 匹配字母或數字或下劃線或漢字 |
\s | 匹配任意空白符 |
\d | 匹配數字 |
\b | 匹配單詞開始或結束 |
^ | 匹配字符串開始 |
$ | 匹配字符串結束 |
一個一個的來講解吧
“.”這個元字符匹配處換行外的任意字符,同樣舉例說明"cat at car".match(/\bat\b.car/g)就會返回["at car"];
\w匹配的東西一般都是我們表單中輸入框允許輸入的東西例如"cat at %$%car ".match(/\w/g)就會返回["c", "a", "t", "a", "t", "c", "a", "r"];
\s匹配任意空白符,一般情況下我們都要處理用戶輸入的空白符"cat at %$%car ".replace(/\s/g,'')就會返回"catat%$%car";
\d匹配數字,我們上面也舉過這個例子"1 and 2 and 3".match(/\d/g)這樣的話就返回["1", "2", "3"];
^匹配你要用來查找的字符串的開頭,$匹配結尾。這兩個代碼在驗證輸入的內容時非常有用,比如一個表單需要驗證你的qq號必須是數字/^\d+$/g.test("123")這裏+意思是匹配一次或更多次
通常情況下這些元字符都不夠用,下表就列出來一些常用限定符
表2. 常用的限定符
代碼/語法 | 說明 |
* | 重複零次或更多次 |
+ | 重複一次或更多次 |
? | 重複零次或一次 |
{n} | 重複n次 |
{n,} | 重複n次或更多次 |
{n,m} | 重複n到m次 |
*與上面例子中的+基本是一樣的用法只是能不能重複零次問題 舉例:/^a\w*d$/g.test("ad")會返回true而/^a\w+d$/g.test("ad")則返回false因爲字母a後面的字母數字下劃線等匹配數爲零。
?是我們在實際應用中用的最多的一個限定符,它限定匹配的字符出現一次或者不出現都會匹配成功例如我們匹配一個電話號碼約定是可以四位數字+"-"+七位數字,那麼就應該這麼寫:
/^\d{4}[-]?\d{5}$/g.test("012323222")與/^\d{4}[-]?、d{5}$/g.test("0123-23222")都會返回true
{}的用法剛纔也說到了,舉個栗子吧:我們要匹配5到十二位qq號/^\d{5,12}$/g.test('12345')返回true其他任何包含非數字或者不在5到12位數之內的都會返回false;
講了這麼多元字符和限定符,你可能會有疑問了,如果我的字符中出現*之類的怎麼辦。這時候你就需要用正則表達式的轉義了,其實很簡單例如你要匹配*只需要/\d+\*/g即可,例如:/\d+\*/g.test("123*")就可以返回true了
[]用法:字符數組,如果我們想在一個字符串中尋找特定的未定義過的幾個字符怎麼辦呢。例如我想要在字符中找出love幾個單詞的匹配,那麼很簡單你只需要用[love]把你需要的列進去就可以了,
這個意思就是匹配任何一個love包含的字母;[]還可以指定一個範圍[0-9a-zA-Z]匹配一個數字或者字母;說明:所有元字符在字符數組內部都是普通字符-不在開頭除外。
()用法:()在使用時候沒有特定含義,只是作爲輔助用在分組指定子表達式用:如果我們想查找一組特定含義的內容重複3次,例如ip,那麼就可以用到()了/^(\d{1,3}\.){3}\d{1,3}$/g;
當然這個ip匹配肯定是有問題的,我給大家一個正確的匹配 大家可以根據前面講的綜合分析一下/^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$/g
很多時候我們需要查找不屬於某個匹配的字符,比如想查找一個html標籤的內容而不包含標籤本身,那麼這時候我們就要用到反義了。
表3.常用的反義代碼
代碼/語法 | 說明 |
\W | 匹配任意不是字母數字下換線漢字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非數字的字符 |
\B | 匹配不是單詞開頭或結束位置 |
[^x] | 匹配除了x以外的任意字符 |
[^abcde] | 匹配除了abcde這幾個字母以外的任意字符 |
例如我們想搜索var tt="gaga<a src='ni'>nihao</a>gaga"中的a標籤那麼就可以用tt.match(/<a.*>+[^<]+<\/a>/g);
捕獲
我們單獨把捕獲拿出來作爲一部分進行詳細講解,開始時候我們講到了捕獲,所謂捕獲就是用小括號指定一個子表達式後,該表達式可以在表達式或者其他程序中做進一步處理,
上面說到用於exec方法,其實捕獲不僅僅能用於exec方法中,在重複匹配某個單詞或者字母時候捕獲也能發揮它的作用,
默認情況下,每個捕獲組會自動擁有一個組號,規則是:從左向右,以分組的左括號爲標誌,第一個出現的分組的組號爲1,第二個爲2,以此類推,可以爲分組指定命名。
例如:
(?<y>\d{4})-(?<md>\d{2}-(?<d>\d{2}))
這個表達式由三對小括號組成分爲四個組號,特別說明的是組號0代表整個表達是整體下表列出匹配結果及分組命名情況如下:
例如匹配日期2013-10-21
編號 | 命名 | 捕獲組 | 匹配內容 |
0 | (?<y>\d{4})-(?<md>\d{2}-(?<d>\d{2})) | 2013-10-21 | |
1 | y | (?<y>\d{4}) | 2013 |
2 | md | (?<md>\d{2}-(?<d>\d{2})) | 10-21 |
3 | d | (?<d>\d{2}) | 21 |
- 反響引用,即對前面捕獲到內容進行引用
- 作爲條件判斷結構
- 在程序中對捕獲組內容的引用
到這裏爲止你是不是覺得你會用正則表達式做任何匹配校驗替換了?
那麼你試試匹配一個規則:輸入的內容可以是純中文可以是純字母也可以是字母中文組合。
怎麼樣,知識不夠用了吧。這種可以也可以的情況下就要用到正則表達式的分支條件了,分支條件就是用|把不同的規則分開去匹配例如/n|b/g匹配n或者b;
ok至此爲止正則表達式的基礎就這些了 我們來做個練習然後分析一下:
就拿最常用的檢測郵箱規則吧:
郵箱規則是字母數字下劃線.|_後三者不能作爲結尾且不能連續重複出現加上@然後是字母數字下劃線.|_加上.然後是com或者cn
/^([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|_|.]?)*[a-zA-Z0-9]+\.(com|cn)$/g;
分析如下首先()內部分可以重複多次,小括號內是以字母數字下劃線開始然後是_|.可以其中一個出現一次或者不出現。然後是字母數字下劃線作爲@的前綴,之後一個@字符,然後是同樣跟@前規則一樣的表達式,
之後是一個.最後以com或者cn結尾;
練習2:去除字符串中重複字符:
var a="abbcccdddeeeffghh";
var b=a.replace(/(.)\1+/g,"$1");
結果b:"abcdefgh"
分析:此處正則表達式中()內部分就是捕獲內容,\1則是捕獲第一組,$1表示第一個捕獲的內容
練習3:將首字母轉化爲大寫
var reg=/\b(\w)|\s(\w)/g;
var
str='hello kitty';
str.replace(reg,function(d){return
d.toUpperCase()})
結果爲:‘Hello Kitty’