本文是 重溫基礎 系列文章的第九篇。
今日感覺:時間管理-角色管理法。前端
系列目錄:git
本章節複習的是JS中的正則表達式,JS中用來匹配字符串的強大工具。github
前置知識:
JS中的正則表達式是用來匹配字符串中指定字符組合的模式。
另外須要記住:正則表達式也是對象。正則表達式
let reg = /ab+c/;
let reg = /^[a-zA-z]/gi;
複製代碼
RegExp
對象:new RegExp(str[, attr])
接收2個參數,str
是一個字符串,指定正則表達式匹配規則,attr
可選,表示匹配模式,值有g
(全局匹配),i
(區分大小寫的匹配)和m
(多行匹配)。let reg = new RegExp('ab+c');
let reg = new RegExp(/^[a-zA-z]/, "gi");
let reg = new RegExp("^[a-zA-z]", "gi");
複製代碼
正則表達式的返回值,是一個新的RegExp
對象,具備指定的模式和標誌。
返回信息介紹:數組
對象 | 屬性 | 描述 | 案例中對應的值 |
---|---|---|---|
reg |
lastIndex |
下一個匹配的索引(僅在使用g 參數時可用) |
0 |
reg |
source |
模式文本。在正則表達式建立時更新,不執行。 | "ab+c" |
reg |
ignoreCase |
是否使用了 "i" 標記使正則匹配忽略大小寫。 | true |
reg |
global |
是否使用了 "g" 標記來進行全局的匹配。 | true |
reg |
multiline |
是否使用了 "m" 標記使正則工做在多行模式。 | false |
關於正則表達式的一些方法屬性,文章後面介紹,這裏先複習定義和使用。微信
JS的正則表達式能夠被用於:ide
RegExp
對象的exec
和test
方法;String
對象的match
、replace
、search
和split
方法。方法 | 介紹 |
---|---|
exec |
檢索字符串中指定的值。返回找到的值,並肯定其位置。 |
test |
檢索字符串中指定的值。返回 true 或 false 。 |
exec(str)
str
: 須要檢索的字符串。
若檢索成功,返回匹配的數組,不然返回null。函數
let str = "hello leo!";
let reg = new RegExp("leo", "g");
let result = reg.exec(str);
// 也能夠寫成
let result = /leo/g.exec("hello leo!");
/* [ 0: "leo", groups: undefined, index: 6, input: "hello leo!", length: 1 ] */
let result2 = /(leo \S)/g.exec("hello leo hi leo!");
/* 0: "leo hi" 1: "leo hi" 2: "hi" groups: undefined index: 6 input: "hello leo hi leo!" length: 3 */
複製代碼
返回信息介紹:工具
對象 | 屬性 | 描述 | 案例中對應的值 |
---|---|---|---|
result |
[0] |
匹配到的全部字符串 | "leo" |
result |
input |
初始字符串。 | "hello leo!" |
result |
index |
在輸入的字符串中匹配到的以0開始的索引值。 | 6 |
result2 |
[1],...,[n] |
括號中的分組捕獲 | [1]=> "leo hi";[2] => "hi" |
test(str)
str
:須要檢索的字符串。
若匹配成功返回true
不然false
。
等價於 reg.exec(str) != null
。post
let str = "hello leo!";
let res = /^leo/.test(str); // fasle
let res1 = /^leo/.test(str); // true
複製代碼
^str
表示匹配以str
開頭的字符串,這些符號文章後面會介紹。
方法 | 介紹 |
---|---|
search |
檢索與正則表達式相匹配的值。 |
match |
找到一個或多個正則表達式的匹配。 |
replace |
替換與正則表達式匹配的子串。 |
split |
把字符串分割爲字符串數組。 |
search
str.search(reg)
:
str
:被檢索的源字符串。
reg
:能夠是須要檢索的字符串,也能夠是須要檢索的RegExp
對象,能夠添加標誌,如i
。
若檢索成功,返回第一個與RegExp
對象匹配的字符串的起始位置,不然返回-1
。
let str = "hello leo!";
let res = str.search(/leo/g); // 6
let str1 = "hello leoleoleoleo!";
let res1 = str.search(/leo/g); // 6
let res2 = str.search(/pingan/g); // -1
複製代碼
match
str.match(reg)
:
str
:被檢索的源字符串。
reg
:能夠是須要檢索的字符串,也能夠是須要檢索的RegExp
對象,能夠添加標誌,如i
。
若檢索成功,返回與reg
匹配的全部結果的一個數組,數組的第一項是進行匹配完整的字符串,以後的項是用圓括號捕獲的結果,不然返回null
。
let str = 'For more information, see Chapter 3.4.5.1';
let reg = /see (chapter \d+(\.\d)*)/i;
let result = str.match(reg);
/* logs [ 'see Chapter 3.4.5.1', 'Chapter 3.4.5.1', '.1', index: 22, input: 'For more information, see Chapter 3.4.5.1' ] */
複製代碼
'see Chapter 3.4.5.1'
是整個匹配。
'Chapter 3.4.5.1'
被'(chapter \d+(\.\d)*)'
捕獲。
'.1'
是被'(\.\d)'
捕獲的最後一個值。
'index'
屬性(22)
是整個匹配從零開始的索引。
'input'
屬性是被解析的原始字符串。
replace
將字符串中指定字符替換成其餘字符,或替換成一個與正則表達式匹配的字符串。
str.replace(sub/reg,val)
:
str
: 源字符串sub
: 使用字符串來檢索被替換的文本reg
: 使用RegExp對象來檢索來檢索被替換的文本val
: 指定替換文本let str = "hello leo!";
let res = str.replace('leo','pingan');//"hello pingan!"
複製代碼
val可使用特殊變量名:
變量名 | 表明的值 |
---|---|
$$ |
插入一個 "$"。 |
$& |
插入匹配的子串。 |
$ |
插入當前匹配的子串左邊的內容。 |
$' |
插入當前匹配的子串右邊的內容。 |
$n |
假如第一個參數是 RegExp對象,而且 n 是個小於100的非負整數,那麼插入第 n 個括號匹配的字符串。提示:索引是從1開始 |
let str = "hello leo!";
let res = str.replace(/(\w+)\s* \s*(\w+)/, "$2:$1");
// "leo:hello!"
複製代碼
split
將一個字符串,按照指定符號分割成一個字符串數組。
str.split(sub[, maxlength])
:
str
: 源字符串sub
: 指定的分割符號或正則maxlength
: 源字符串let str = "hello leo!";
let res = str.split(); //["hello leo!"]
let res = str.split(""); //["h", "e", "l", "l", "o", " ", "l", "e", "o", "!"]
let res = str.split(" ");//["hello", "leo!"]
let res = str.split(/\s+/);//["hello", "leo!"]
let res = str.split("",3);//["h", "e", "l"]
複製代碼
test
或search
方法。exec
或match
方法。詳細的每一個符號的用法,能夠查閱 W3school JavaScript RegExp 對象
修飾符 | 描述 |
---|---|
i |
執行對大小寫不敏感的匹配。 |
g |
執行全局匹配(查找全部匹配而非在找到第一個匹配後中止)。 |
m |
執行多行匹配。 |
let str = "hello leo!"
let res = /Leo/i.test(str); // i 不區分大小寫 因此返回true
let res = /Leo/.test(str); // fasle
複製代碼
用於查找指定返回以內的字符:
表達式 | 描述 |
---|---|
[abc] |
查找方括號之間的任何字符。 |
[^abc] |
查找任何不在方括號之間的字符。 |
[0-9] |
查找任何從 0 至 9 的數字。 |
[a-z] |
查找任何從小寫 a 到小寫 z 的字符。 |
[A-Z] |
查找任何從大寫 A 到大寫 Z 的字符。 |
[A-z] |
查找任何從大寫 A 到小寫 z 的字符。 |
[adgk] |
查找給定集合內的任何字符。 |
[^adgk] |
查找給定集合外的任何字符。 |
(red) |
查找任何指定的選項。 |
let str = "hello leo!";
let res = str.match(/[a-m]/g);
//["h", "e", "l", "l", "l", "e"]
let res = str.match(/[^a-m]/g);
//["o", " ", "o", "!"]
複製代碼
元字符是擁有特殊含義的字符:
元字符 | 描述 |
---|---|
. |
查找單個字符,除了換行和行結束符。 |
\w |
查找單詞字符。 |
\W |
查找非單詞字符。 |
\d |
查找數字。 |
\D |
查找非數字字符。 |
\s |
查找空白字符。 |
\S |
查找非空白字符。 |
\b |
匹配單詞邊界。 |
\B |
匹配非單詞邊界。 |
\0 |
查找 NUL 字符。 |
\n |
查找換行符。 |
\f |
查找換頁符。 |
\r |
查找回車符。 |
\t |
查找製表符。 |
\v |
查找垂直製表符。 |
\xxx |
查找以八進制數 xxx 規定的字符。 |
\xdd |
查找以十六進制數 dd 規定的字符。 |
\uxxxx |
查找以十六進制數 xxxx 規定的 Unicode 字符。 |
let str = "hello leo hi pingan!";
let res = str.match(/o\s/g);
//["o ", "o "]
let res = str.match(/\s/g);
//[" ", " ", " "]
複製代碼
量詞 | 描述 |
---|---|
n+ |
匹配任何包含至少一個 n 的字符串。 |
n* |
匹配任何包含零個或多個 n 的字符串。 |
n? |
匹配任何包含零個或一個 n 的字符串。 |
n{X} |
匹配包含 X 個 n 的序列的字符串。 |
n{X,Y} |
匹配包含 X 至 Y 個 n 的序列的字符串。 |
n{X,} |
匹配包含至少 X 個 n 的序列的字符串。 |
n$ |
匹配任何結尾爲 n 的字符串。 |
^n |
匹配任何開頭爲 n 的字符串。 |
?=n |
匹配任何其後緊接指定字符串 n 的字符串。 |
?!n |
匹配任何其後沒有緊接指定字符串 n 的字符串。 |
let str = "hello leo!";
let res = str.match(/^hello/g);
// ["hello"]
let res = str.match(/^pingan/g);
//null
複製代碼
在ES5中有兩種狀況。
let a = new RegExp('abc', 'i');
// 等價於
let a = /abx/i;
複製代碼
let a = new RegExp(/abc/i);
//等價於
let a = /abx/i;
let a = new RegExp(/abc/, 'i');
// Uncaught TypeError
複製代碼
ES6中使用:
第一個參數是正則對象,第二個是指定修飾符,若是第一個參數已經有修飾符,則會被第二個參數覆蓋。
new RegExp(/abc/ig, 'i');
複製代碼
經常使用的四種方法:match()
、replace()
、search()
和split()
。
添加u
修飾符,是爲了處理大於uFFFF
的Unicode字符,即正確處理四個字節的UTF-16編碼。
/^\uD83D/u.test('\uD83D\uDC2A'); // false
/^\uD83D/.test('\uD83D\uDC2A'); // true
複製代碼
因爲ES5以前不支持四個字節UTF-16編碼,會識別爲兩個字符,致使第二行輸出true
,加入u
修飾符後ES6就會識別爲一個字符,因此輸出false
。
注意:
加上u
修飾符後,會改變下面正則表達式的行爲:
.
)在正則中表示除了換行符之外的任意單個字符。對於碼點大於0xFFFF
的Unicode字符,點字符不能識別,必須加上u
修飾符。var a = "𠮷";
/^.$/.test(a); // false
/^.$/u.test(a); // true
複製代碼
u
修飾符,才能識別大括號。/\u{61}/.test('a'); // false
/\u{61}/u.test('a'); // true
/\u{20BB7}/u.test('𠮷'); // true
複製代碼
u
修飾符後,全部量詞都會正確識別碼點大於0xFFFF
的 Unicode 字符。/a{2}/.test('aa'); // true
/a{2}/u.test('aa'); // true
/𠮷{2}/.test('𠮷𠮷'); // false
/𠮷{2}/u.test('𠮷𠮷'); // true
複製代碼
u
修飾符,就沒法識別非規範的K
字符。/[a-z]/i.test('\u212A') // false
/[a-z]/iu.test('\u212A') // true
複製代碼
檢查是否設置u
修飾符: 使用unicode
屬性。
const a = /hello/;
const b = /hello/u;
a.unicode // false
b.unicode // true
複製代碼
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"] 剩餘 '_aa_a'
r2.exec(s) // null
複製代碼
lastIndex
屬性: 指定匹配的開始位置:
const a = /a/y;
a.lastIndex = 2; // 從2號位置開始匹配
a.exec('wahaha'); // null
a.lastIndex = 3; // 從3號位置開始匹配
let c = a.exec('wahaha');
c.index; // 3
a.lastIndex; // 4
複製代碼
返回多個匹配:
一個y
修飾符對match
方法只能返回第一個匹配,與g
修飾符搭配能返回全部匹配。
'a1a2a3'.match(/a\d/y); // ["a1"]
'a1a2a3'.match(/a\d/gy); // ["a1", "a2", "a3"]
複製代碼
檢查是否使用y
修飾符:
使用sticky
屬性檢查。
const a = /hello\d/y;
a.sticky; // true
複製代碼
flags
屬性返回全部正則表達式的修飾符。
/abc/ig.flags; // 'gi'
複製代碼
在正則表達式中,點(.
)能夠表示任意單個字符,除了兩個:用u
修飾符解決四個字節的UTF-16字符,另外一個是行終止符。
終止符即表示一行的結束,以下四個字符屬於「行終止符」:
/foo.bar/.test('foo\nbar')
// false
複製代碼
上面代碼中,由於.
不匹配\n
,因此正則表達式返回false
。
換個醒,能夠匹配任意單個字符:
/foo[^]bar/.test('foo\nbar')
// true
複製代碼
ES9引入s
修飾符,使得.
能夠匹配任意單個字符:
/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
不衝突,二者一塊兒使用的狀況下,.
匹配全部字符,而^
和$
匹配每一行的行首和行尾。
1.MDN 正則表達式
2.W3school JavaScript RegExp 對象
本部份內容到這結束
Author | 王平安 |
---|---|
pingan8787@qq.com | |
博 客 | www.pingan8787.com |
微 信 | pingan8787 |
每日文章推薦 | github.com/pingan8787/… |
JS小冊 | js.pingan8787.com |
歡迎關注個人微信公衆號【前端自習課】