【JS】Javascript正則表達式學習筆記

正則表達式修飾符

修飾符 可以在全局搜索中不區分大小寫:

修飾符 描述
i 執行對大小寫不敏感的匹配。
g 執行全局匹配(查找所有匹配而非在找到第一個匹配後停止)。
m 執行多行匹配。

正則表達式模式

(1)方括號用於查找某個範圍內的字符:

表達式 描述
[abc] 查找方括號之間的任何字符。
[0-9] 查找任何從 0 至 9 的數字。
(x|y) 查找任何以 | 分隔的選項。
() 小括號,叫做分組符,正則中的每一個帶小括號的項,都叫做這個正則的子項

(2)元字符是擁有特殊含義的字符:

元字符 描述
\d 查找數字。
\D 查找非數字。
\s 查找空白字符。
\S 查找非空白字符。
\w 字符 ( 字母 ,數字,下劃線_ )
\W 非字符
\b 匹配單詞邊界。
\uxxxx 查找以十六進制數 xxxx 規定的 Unicode 字符。
.(點) 任意字符
. 真正的點
\b 獨立的部分 ( 起始,結束,空格 )
\B 非獨立的部分
\a 表示重複的某個子項;\1 重複的第一個子項;\2 重複的第二個子項

(3)量詞:

量詞 描述
n+ 匹配任何包含至少一個 n 的字符串。
n* 匹配任何包含零個或多個 n 的字符串。
n? 匹配任何包含零個或一個 n 的字符串。
{n,m} 至少出現n次,最多m次
{n,} 至少n次
{n} 正好n次

使用 RegExp 對象

在 JavaScript 中,RegExp 對象是一個預定義了屬性和方法的正則表達式對象。

使用 test()

test() 方法是一個正則表達式方法。
test() 方法用於檢測一個字符串是否匹配某個模式,如果字符串中含有匹配的文本,則返回 true,否則返回 false。

使用 exec()

exec() 方法是一個正則表達式方法。
exec() 方法用於檢索字符串中的正則表達式的匹配。
該函數返回一個數組,其中存放匹配的結果。如果未找到匹配,則返回值爲 null。

match()

在字符串中搜索複合規則的內容,搜索成功就返回內容,格式爲數組,失敗就返回null。
用法: 字符串.match(正則)
量詞:+ 至少出現一次 匹配不確定的次數(匹配就是搜索查找的意思)
全局匹配:g——global(正則中默認,只要搜索到複合規則的內容就會結束搜索 )

replace()

查找符合正則的字符串,就替換成對應的字符串。返回替換後的內容。
用法: 字符串.replace(正則,新的字符串/回調函數)(在回調函數中,第一個參數指的是每次匹配成功的字符)
| : 或的意思
eg: 敏感詞過濾,比如 我愛北京天安門,天安門上太陽昇。——我愛,***上太陽昇。即北京和天安門變成*號,

var str = "我愛北京天安門,天安門上太陽昇。";
var re = /北京|天安門/g; // 找到北京 或者天安門 全局匹配
var str2 = str.replace(re,function(str){
       alert(str); //用來測試:函數的第一個參數代表每次搜索到的符合正則的字符,所以第一次str指的是北京 第二次str是天安門 第三次str是天安門
      var result = '';
      for(var i=0;i<str.length;i++){
        result += '*';
      }        
      return result; //所以搜索到了幾個字就返回幾個* 
    });
alert(str2) //我愛*****,***上太陽昇     

//整個過程就是,找到北京,替換成了兩個*,找到天安門替換成了3個*,找到天安門替換成3個*。


ES6正則的擴展

u 修飾符

ES6 對正則表達式添加了u修飾符,含義爲“Unicode 模式”,用來正確處理大於\uFFFF的 Unicode 字符。也就是說,會正確處理四個字節的 UTF-16 編碼

一旦加上u修飾符號,就會修改下面這些正則表達式的行爲:
(1)點字符
點(.)字符在正則表達式中,含義是除了換行符以外的任意單個字符。對於碼點大於0xFFFF的 Unicode 字符,點字符不能識別,必須加上u修飾符。(以下代碼中的?是個漢字的偏僻字(碼點大於0xFFFF的 Unicode 字符),正常顯示不出來,目前還不知道如何設置可以正常顯示,若有知道的望告知。)

var s = '?';

/^.$/.test(s) // false
/^.$/u.test(s) // true

上面代碼表示,如果不添加u修飾符,正則表達式就會認爲字符串爲兩個字符,從而匹配失敗。

(2)Unicode 字符表示法
ES6 新增了使用大括號表示 Unicode 字符,這種表示法在正則表達式中必須加上u修飾符,才能識別當中的大括號,否則會被解讀爲量詞。

/\u{61}/.test('a') // false
/\u{61}/u.test('a') // true
/\u{20BB7}/u.test('?') // true

上面代碼表示,如果不加u修飾符,正則表達式無法識別\u{61}這種表示法,只會認爲這匹配 61 個連續的u。

(3)量詞
使用u修飾符後,所有量詞都會正確識別碼點大於0xFFFF的 Unicode 字符。

/a{2}/.test('aa') // true
/a{2}/u.test('aa') // true
/?{2}/.test('??') // false
/?{2}/u.test('??') // true

(4)預定義模式
u修飾符也影響到預定義模式,能否正確識別碼點大於0xFFFF的 Unicode 字符。

/^\S$/.test('?') // false
/^\S$/u.test('?') // true

上面代碼的\S是預定義模式,匹配所有非空白字符。只有加了u修飾符,它才能正確匹配碼點大於0xFFFF的 Unicode 字符。

(5)i 修飾符
有些 Unicode 字符的編碼不同,但是字型很相近,比如,\u004B與\u212A都是大寫的K。

/[a-z]/i.test('\u212A') // false
/[a-z]/iu.test('\u212A') // true

上面代碼中,不加u修飾符,就無法識別非規範的K字符。

y 修飾符

ES6 還爲正則表達式添加了y修飾符,叫做“粘連”(sticky)修飾符。

y修飾符的作用與g修飾符類似,也是全局匹配,後一次匹配都從上一次匹配成功的下一個位置開始。不同之處在於,g修飾符只要剩餘位置中存在匹配就可,而y修飾符確保匹配必須從剩餘的第一個位置開始,這也就是“粘連”的涵義。

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;

r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]

r1.exec(s) // ["aa"]
r2.exec(s) // null

上面代碼有兩個正則表達式,一個使用g修飾符,另一個使用y修飾符。這兩個正則表達式各執行了兩次,第一次執行的時候,兩者行爲相同,剩餘字符串都是_aa_a。由於g修飾沒有位置要求,所以第二次執行會返回結果,而y修飾符要求匹配必須從頭部開始,所以返回null。

s 修飾符:dotAll 模式

正則表達式中,點(.)是一個特殊字符,代表任意的單個字符,但是有兩個例外。一個是四個字節的 UTF-16 字符,這個可以用u修飾符解決;另一個是行終止符(line terminator character)。

所謂行終止符,就是該字符表示一行的終結。以下四個字符屬於”行終止符“。

  • U+000A 換行符(\n)
  • U+000D 回車符(\r)
  • U+2028 行分隔符(line separator)
  • U+2029 段分隔符(paragraph separator)
/foo.bar/.test('foo\nbar')
// false

上面代碼中,因爲.不匹配\n,所以正則表達式返回false。

/foo.bar/s.test('foo\nbar') // true

這被稱爲dotAll模式,即點(dot)代表一切字符。所以,正則表達式還引入了一個dotAll屬性,返回一個布爾值,表示該正則表達式是否處在dotAll模式。

const re = /foo.bar/s;
// 另一種寫法
// const re = new RegExp('foo.bar', 's');

re.test('foo\nbar') // true
re.dotAll // true
re.flags // 's'

/s修飾符和多行修飾符/m不衝突,兩者一起使用的情況下,.匹配所有字符,而^和$匹配每一行的行首和行尾。

參考資料

ES6入門 阮一峯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章