js基礎(三):正則方法和支持正則表達式的String對象方法

RegExp對象匹配正則表達式方法:
1、exec()方法,檢索字符串中指定的值。返回找到的值,並確定其位置。
2、test()方法,檢索字符串中指定的值。返回 true 或 false。
3、toString()方法,返回正則表達式的字符串。

String對象匹配正則表達式方法:
1、search()方法,檢索與正則表達式相匹配的值。
2、match()方法,找到一個或多個正則表達式的匹配。
3、replace()方法,替換與正則表達式匹配的子串。
4、split()方法,把字符串分割爲字符串數組。

RegExp對象方法詳解:

1、RegExp.exec()
exec() 方法用於檢索字符串中的正則表達式的匹配。
①如果沒有匹配到數據時返回 null。
②如果字符串中有匹配的值則返回該匹配值構成的數組 。此數組的第 0 個元素是與正則表達式相匹配的文本,第 1 個元素是與 RegExpObject 的第 1 個子表達式相匹配的文本(如果有的話),第 2 個元素是與 RegExpObject 的第 2 個子表達式相匹配的文本(如果有的話)。除了數組元素和 length 屬性之外,exec() 方法還返回三個屬性:

groups:是一個新的field,用來存儲命名捕獲組的信息。 // ECMAScript 2018草案中定義
index:表示匹配文本的第一個字符的位置。
input:表示被檢索的字符串。

捕獲組:/123(\d+)0/ 括號中的被稱之爲捕獲組。

// groups屬性的應用
// 正常匹配
let reg1 = /(\d)(\d)/;
let str1 = '123';
console.log('正常匹配',reg1.exec(str1));

// 命名捕獲組
let reg2 = /(?<first>\d)(?<second>\d)/;
let str2 = '123';
console.log('命名捕獲組',reg2.exec(str2))

結果如下圖:
在這裏插入圖片描述
非捕獲組
先來看個例子:

let nameList = `
Brandon Stark
Sansa Stark
John Snow
`
let reg = /^\w+(?=\s?Stark)/gm;
let notCatch = nameList.match(reg); 
console.log(notCatch); // => ["Brandon", "Sansa"]

上邊的(?=)就是非捕獲組,意思就是規則會被命中,但是在結果中不會包含它(Stark)。

比如我們想實現一個比較常用的功能,給數組添加千分位:

function numberWithCommas (x = 0) {
  return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

numberWithCommas(123) // => 123
numberWithCommas(1234) // => 1,234

\B代表匹配一個非單詞邊界,也就是說,實際他並不會替換掉任何的元素。
其次,後邊的非捕獲組這麼定義:存在三的倍數個數字(3、6、9),並且這些數字後邊沒有再跟着其他的數字。
因爲在非捕獲組中使用的是(\d{3})+,貪婪模式,所以就會盡可能多的去匹配。
如果傳入字符串1234567,則第一次匹配的位置在1和2之間,第二次匹配的位置在4和5之間。
獲得的最終字符串就是1,234,567。

2、RegExp.test()
test()方法用來檢查正則是否能成功匹配該字符串。

let reg = /^Hello/;
reg.test('Hello World'); // => true
reg.test('Say Hello'); // => false

test方法一般來說多用在檢索或者過濾的地方。
比如我們做一些篩選filter的操作,用test就是一個很好的選擇。

// 篩選出所有名字爲 Niko的數據
let data = [{ name: 'Niko Bellic' }, { name: 'Roman Bellic'}]
data.filter(({name}) => /^Niko/.test(name)) // => [{ name: 'Niko Bellic' }]

String對象方法詳解:

1、string.search()
傳入一個正則表達式,並使用該表達式進行匹配。
如果匹配失敗,則會返回-1。
如果匹配成功,則會返回匹配開始的下標。
可以理解爲是一個正則版的indexOf。

'Hi Niko'.search(/Niko/) // => 3
'Hi Niko'.search(/Roman/) // => -1
// 如果傳入的參數爲一個字符串,則會將其轉換爲`RegExp`對象
'Hello'.search('llo') // => 2

2、string.match()
match方法用來檢索字符串,並返回匹配的結果,,結果爲一個數組。
如果正則沒有添加g標識的話,返回值與exec類似。
但是如果添加了g標識,則會返回一個數組,數組的item爲滿足匹配條件的子串。
這將會無視掉所有的捕獲組。

let html = '<p><span>text1</span><span>text2</span></p>'
html.match(/<span>(.+?)<\/span>/g) // => ["<span>text1</span>", "<span>text2</span>"]
html.match(/<span>(.+?)<\/span>/) 
/** =>
[
	0: "<span>text1</span>"
	1: "text1"
	groups: undefined
	index: 3
	input: "<p><span>text1</span><span>text2</span></p>"
	length: 2
	__proto__: Array(0)
]
*/

3、string.replace()
replace應該是與正則有關的應用最多的一個函數。
最簡單的模版引擎可以基於replace來做。
日期格式轉換也可以通過replace來做。
甚至match的功能也可以通過replace來實現。

replace接收兩個參數
replace(str|regexp, newStr|callback)

第一個參數可以是一個字符串,也可以是一個正則表達式,轉換規則同上幾個方法。
第二個參數卻是可以傳入一個字符串,也可以傳入一個回調函數。

當傳入字符串時,會將正則所匹配到的字串替換爲該字符串。
當傳入回調函數時,則會在匹配到子串時調用該回調,回調函數的返回值會替換被匹配到的子串。

'Hi: Jhon'.replace(/Hi:\s(\w+)/g, 'Hi: $1 Snow') // => Hi: Jhon Snow

/**以下匹配回調函數中,
str:匹配的完整串 
$1:捕獲組
*/
'price: 1'.replace(/price:\s(\d)/g, (str,  $1) => `price: ${$1 *= 10}`) // => price: 10

4、string.split()
split方法應該是比較常用的,可以將一個字符串轉換成數組。
然而這個參數也是可以塞進去一個正則表達式的。

// 使用正則表達式分割
'1,2|3'.split(/,|\|/); // => ["1", "2", "3"]

// 將一個日期時間字符串進行分割
let date = '2017-11-21 23:40:56';
date.split(/-|\s|:/);  // => ["2017", "11", "21", "23", "40", "56"]

// 又或者我們有這麼一個字符串,要將它正確的分割
let arr = '1,2,3,4,[5,6,7]';
arr.split(','); // => ["1", "2", "3", "4", "[5", "6", "7]"] 這個結果肯定是不對的。
// 所以我們可以這麼寫
arr.split(/,(?![,\d]+])/); // => ["1", "2", "3", "4", "[5,6,7]"]

參考資料:
正則 exec方法 返回數組中 groups是用來存儲什麼值的?
正則表達式小記

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