【js正則表達式】

19.9.22更新:若是看MDN比較有難度的話,建議看這個:正則表達式30分鐘入門教程 這個是按用法來概括的,比較容易理解javascript

學習文檔連接:MDN正則表達式
本身在學習過程當中簡單整理一下java

使用簡單模式

好比,/abc/ 這個模式就能且僅能匹配 「abc」 字符按照順序同時出現的狀況。web

使用特殊字符

斷言

表示一個匹配在某些條件下發生。斷言包含先行斷言、後行斷言和條件表達式。正則表達式

概括

字符 含義 詳細
x(?=y) 先行斷言 僅當x後跟y時才匹配x
(?<=y)x 後行斷言 僅當x前面帶y時才匹配x
x(?!y) 正向否認查找 僅當x未跟隨y時才匹配x
(?<!y)x 反向否認查找 僅當x不以y開頭時才匹配x

栗子

栗子1數組

let regex = /First(?= test)/g;

console.log('First test'.match(regex)); // [ 'First' ]
console.log('First peach'.match(regex)); // null
console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
console.log('This is a First peach in a month.'.match(regex)); // null

栗子2app

console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]

栗子3ide

//這個還不懂
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";

// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and Ranges /[^?!]/
let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]

let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]

栗子4svg

let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];

let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]

邊界

表示行和單詞的開始和結尾。函數

概括

字符 含義
^ 匹配輸入的開始
$ 匹配輸入的結束
\b 匹配一個單詞的邊界
\B 匹配一個非單詞邊界

栗子

完整版請看這邊學習

第一個栗子:

// Using Regex boundaries to fix buggy string.
buggyMultiline = `tey, ihe light-greon apple tangs on ihe greon traa`;

buggyMultiline = buggyMultiline.replace(/^t/gim,'h'); 
console.log(1, buggyMultiline); // fix 'tey', 'tangs' => 'hey', 'hangs'. Avoid 'traa'.
/*輸出:1 "hey, ihe light-greon apple hangs on ihe greon traa"*/

buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.'); 
console.log(2, buggyMultiline); // fix 'traa' => 'tree'.
/*輸出:2 "hey, ihe light-greon apple hangs on ihe greon tree."*/

buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
console.log(3, buggyMultiline); // fix 'ihe' but does not touch 'light'.
/*輸出:3 "hey, the light-greon apple hangs on ihe greon tree."*/

fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
console.log(4, fixedMultiline); // fix 'greon' but does not touch 'on'.
/*輸出:4 "hey, the light-green apple hangs on ihe green tree."*/

問題1:
/gim是什麼:
g-global 全局搜索,即不是搜到一個匹配就返回,而是搜出所有匹配。通常返回是一個數組
i- 忽略大小寫搜索
m-多行搜索。之前限於計算機能力,搜索只在每行行首到行尾間進行。好比一個匹配結果在兩行的換行處,就會不匹配了。添加這個,就同時搜索換行的地方
問題2:
爲何第二行的‘tey’被忽略了,不能變成hey?
圖片解釋
從圖片可看出,若是換行了的話,traa就能變成hraa。
所以,這個^,應該是搜索每行,若是搜索成功就不會往該行的後面繼續搜。

第二個栗子:

let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];

// 選擇由'^ A / Regex以'A'開頭的水果。
// 這裏'^'控制符號僅用於一個角色:匹配輸入的開頭。
let fruitsStartsWithA = fruits.filter(fruit => /^A/.test(fruit));
console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]

注意:
ES6新增箭頭函數,fruit =>中的fruit是接收的函數參數

第三個栗子:

let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];

//經過/ ^ [^ A] /正則表達式選擇未由'A'開始的水果。
//在這個例子中,'^'控制符號的兩個含義表示:
// 1)匹配輸入的開頭
// 2)否認或補充的字符集:[^ A]

let fruitsStartsWithNotA = fruits.filter(fruit => /^[^A]/.test(fruit));

console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]

第四個栗子:

let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];

//選擇包含「en」或「ed」字詞結尾的描述:
let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));

console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]

字符類別

區分不一樣類型的字符,例如區分字母和數字。

概括

完整版看這裏

組和範圍

表示表達式字符的分組和範圍。

概括

完整版看這裏

字符 含義 栗子
x|y 匹配x或y
[xyz] 一個字符集 1.[a-c]:匹配a,b,c 2.[-ab]:匹配-,a,b
[^xyz] 一個反向字符集
(x) 捕獲組
\n 其中n是正整數。對正則表達式中與n括號匹配的最後一個子字符串的後引用(計算左括號)。 <=這個沒懂
(?<Name>x) 命名捕獲組 匹配x並將其存儲在由指定的名稱下的返回匹配的groups屬性中。<=這個也沒懂
(?:x) 非捕獲組 匹配 ‘x’ 可是不記住匹配項

量詞

表示匹配的字符或表達式的數量。

概括

完整版

字符 含義
x* 匹配前一個表達式x 0 次或屢次。等價於 {0,}
x+ 匹配前一個表達式x 1次或更屢次。 等價於{1,}
x? 匹配前一個表達式x 0次或1次。等價於{0,1}
x{n} 匹配前一個表達式x的n次出現
x{n,} 匹配前一個表達式x至少出現了n次
x{n,m} 匹配前一個表達式x至少n次,最多m次。

x*?
x+?
x??
x{n}?
x{n,}?
x{n,m}? 這些就去看完整版吧

Unicode 屬性轉義

基於 unicode 字符屬性區分字符。例如大寫和小寫字母、數學符號和標點。

補充

元字符

元字符:( [ { \ ^ $ | ) ? * + . ] }

這些元字符在正則表達式中都有一或多種特殊用途,若想要匹配字符串中包含這些字符,需對它們進行轉義。
因爲RegExp構造函數的模式參數是字符串,對元字符需進行雙重轉義。例如\n(字符\在字符串中被轉義爲\,而在正則表達式字符串中就會變成\\)

栗子以下:

字面量模式 等價的RegExp字符串
/\.at/ "\\.at"
/\[bc\]at/ "\\[bc\\]at"
/\d.\d{1,2}/ "\\d.\\d{1,2}"
/\w\\hello\\123/ "\\w\\\\hello\\\\123"

9.23補充一些例子:見這個連接