正則表達(dá)式起源于對(duì)形式語言(formal language)的數(shù)學(xué)研究伊磺,它趨向于極致而簡(jiǎn)潔的書寫風(fēng)格缎谷,所有的字符擠在一起,不僅難以閱讀婉弹,而且在維護(hù)時(shí)也非常困難。Javascript正則表達(dá)式借鑒自Perl终吼,它不支持注釋和空白镀赌,且處在不同位置的相同字符都可能代表不同的意義。 但是我們?yōu)楹斡忠褂盟兀?這主要是因?yàn)椋?/code>相比等效的字符串處理际跪,Javascript正則表達(dá)式有著明顯的性能優(yōu)勢(shì)商佛。
參考:https://en.wikipedia.org/wiki/Formal_language
下面通過例子來感受一下:
/**
* 處理一個(gè)url串,并捕獲其中的協(xié)議名姆打、主機(jī)名(*)良姆、端口號(hào)、路徑名幔戏、查詢條件和哈希值
* 其中玛追,除了主機(jī)名是捕獲型分組外,其他的皆為非捕獲型
*/
// 以簡(jiǎn)書為例
var url = 'http://www.reibang.com:8080/u/101db3165437?user=JSoon#info';
// 處理后的url
var parsed = /^(?:([a-zA-Z]+):)?(\/{0,2})([a-zA-Z0-9\.\-]*)(?::([0-9]+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:\#(.*))?$/.exec(url);
// 在控制臺(tái)打印
console.log(parsed);
結(jié)果如下圖:
首先來看parsed
,regexp.exec(string)
返回一個(gè)結(jié)果數(shù)組痊剖,數(shù)組的第一項(xiàng)為該正則表達(dá)式的匹配結(jié)果韩玩,不計(jì)入分組。
參考:RegExp.prototype.exec()
從parsed[1]
開始直到parsed[7]
陆馁,則是正則表達(dá)式分組所匹配到的值找颓。
正則表達(dá)式為兩個(gè)正斜杠之間所夾的符號(hào)串/regexp/
組成,在本例中氮惯,第一個(gè)/
后的^
表示以第一個(gè)分組所匹配的字符串開始叮雳,它像一個(gè)錨,只會(huì)匹配以次開頭的字符串妇汗,否則返回null
帘不。最后一個(gè)/
前的$
表示這個(gè)字符串的結(jié)束,這就能確保匹配的精確性杨箭。
分組一:
// 協(xié)議名
(?:([a-zA-Z]+):)? // 匹配一段后邊緊跟一個(gè)冒號(hào)的字符串寞焙。如果沒有,則會(huì)返回undefined互婿,因?yàn)?告訴了正則匹配器捣郊,必須得到至少一個(gè)英文字符
// 匹配結(jié)果
console.log(parsed[1]); // "http"
(?:)
表示這是一個(gè)非捕獲型分組,后面的?
表明這是一個(gè)非貪婪性匹配?
等同于{0,1}
慈参。表示如果整個(gè)字符串中都沒有匹配到這個(gè)字符串呛牲,也不會(huì)影響匹配的進(jìn)行。若去掉這個(gè)?
驮配,而字符串中又沒有如http:
之類的子串娘扩,那么正則匹配將立即結(jié)束,并返回null
壮锻。
其內(nèi)部有一個(gè)捕獲型分組([a-zA-Z]+)
琐旁,[a-zA-Z]
是一個(gè)字符集,它指定了一組字符串猜绣,這里表示所有的大小寫英文字母灰殴,后邊的+
表示貪婪性匹配,等同于{1,}
掰邢,即至少匹配一個(gè)英文字母牺陶。([a-zA-Z]+)
后邊的:
表示這段英文字母后緊接著是一個(gè)冒號(hào),如若不是辣之,匹配也會(huì)失敗掰伸。
分組二:
// 斜杠
(\/{0,2}) // 匹配0到2個(gè)連續(xù)的斜杠。如果沒有斜杠召烂,則會(huì)返回""空串
// 匹配結(jié)果
console.log(parsed[2]); // "http://"
這個(gè)很好理解,在正則中娃承,若想將斜杠之類的特殊字符按照字面量來匹配奏夫,則必須使用反斜杠前綴對(duì)其進(jìn)行轉(zhuǎn)義怕篷。這里一個(gè)小竅門是,如果你拿不準(zhǔn)哪些特殊字符需要轉(zhuǎn)義酗昼,一個(gè)保險(xiǎn)的做法是廊谓,給任何特殊字符都添加一個(gè)反斜杠前綴來使其字面量化。注意反斜杠前綴并不能使字母或數(shù)字字面量化麻削。
分組三:
// 主機(jī)名
([a-zA-Z0-9\.\-]*) // 匹配至少0次包含大小寫英文字母蒸痹,數(shù)字,點(diǎn)號(hào)和連字符
// 匹配結(jié)果
console.log(parsed[3]); // "www.reibang.com"
.
和-
被轉(zhuǎn)義呛哟,將.
轉(zhuǎn)義是一種保險(xiǎn)的做法叠荠,因?yàn)檫@里我并不確定它在字符集中是否代表其他含義;而將-
轉(zhuǎn)義的目的是因?yàn)檫B字符在字符集中表示范圍扫责,如[0-9]
表示[0123456789]
榛鼎。
分組四:
// 端口號(hào)
(?::([0-9]+))? // 匹配以冒號(hào)開始,以及之后的數(shù)字鳖孤。如果沒有者娱,其中的捕獲分組會(huì)返回undefined,因?yàn)?告訴了正則匹配器苏揣,必須得到至少一個(gè)數(shù)字
// 匹配結(jié)果
console.log(parsed[4]); // "8080"
分組五:
// 路徑名
(?:\/([^?#]*))? // 匹配以斜杠開始黄鳍,以及除?和#之外所有的字符
// 匹配結(jié)果
console.log(parsed[5]); // "u/101db3165437"
分組六:
// 查詢條件
(?:\?([^#]*))? // 匹配以?開始,以及除#之外所有的字符
// 匹配結(jié)果
console.log(parsed[6]); // "user=JSoon"
分組七:
// 哈希值
(?:\#(.*))? // 匹配以#開始平匈,除行結(jié)束符以外的所有字符
// 匹配結(jié)果
console.log(parsed[7]); // "info"
特別的框沟,一個(gè)未被轉(zhuǎn)移的.
會(huì)匹配除行結(jié)束符\n
和\r
以外的任何字符。
若還需要對(duì)匹配結(jié)果進(jìn)行再匹配吐葱,則可以對(duì)結(jié)果再次進(jìn)行正則處理街望,這里就不細(xì)說了。
當(dāng)然弟跑,除了用正則表達(dá)式字面量來創(chuàng)建正則表達(dá)式外灾前,還可以使用
RegExp
構(gòu)造函數(shù)來實(shí)現(xiàn)。RegExp
適用于需要?jiǎng)討B(tài)生成正則表達(dá)式孟辑,而不是事先就明確正則條件的情況時(shí)使用哎甲。
參考:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp
可以處理正則表達(dá)式的方法:
regexp.exec // 返回匹配結(jié)果的數(shù)組
regexp.test // 返回true or false
string.match // 返回與regexp.exec相同
string.replace // 用正則對(duì)匹配結(jié)果進(jìn)行替換,返回替換后的新字符串
string.search // 返回匹配到的字符串的第一個(gè)字符的位置饲嗽,若匹配失敗炭玫,則返回-1
string.split // 用正則匹配到的字符作為分割器,然后返回分割后的各個(gè)字符的數(shù)組
歡迎交流貌虾,完吞加。