JS正則表達式學習筆記1

正則表達式作爲前端學習的一個知識點,是每個合格的前端開發都應該掌握它的用法。正則表達式的學習確實不難,語法和應用也非常簡單,能夠快速入門,很輕鬆的就能寫出簡單的表達式來對字符串執行某些操作。網上也有標題黨說一杯咖啡的時間就能學會。能學會嗎?能!但要真正的掌握卻不易,就好比籃球運動,40分鐘的一節課,就能學會基本的規則和投球方法,但要做到非常優秀,就需要長時間的練習,學習正則表達式也一樣,其實,學習任何知識和技能都是如此,唯有長時間的練習,儘量避免少犯錯誤,才能達到專業;廢話說了一籮筐,下面進入正題;

在實際工作當中,正則表達式應用的場景有:

  1. 表單驗證

    1. 驗證郵箱
    2. 驗證電話
    3. 是否爲空
    4. etc
  2. 替換字符串
  3. 檢索字符串
  4. 開發工具當中的查找和替換

簡單來說,正則表達式是對字符串操作的一種邏輯公式,用一些約定好的字符組合對字符串執行檢索、匹配、替換等操作。

本文會把學習路徑分爲兩個階段:

第一階段,熟悉正則,有一個正確的認識,能夠寫出簡單的正則表達式來操作字符串;

第二階段,熟練運用正則的一些高級用法,掌握心法,需要時,信手拈來。

第一階段

需要掌握的內容包括:

  1. 如何定義一個正則表達式
  2. 定義了正則,在那些方法中使用
  3. 元字符
  4. 字符類&字符轉義
  5. 範圍&量詞
  6. 分支條件
  7. 反義

如何定義一個正則表達式

有兩種方式:

  1. 通過實例化RegExp構造函數

    1. 有兩個參數,第一個是表達式,第二個是修飾符
  2. 使用字面量把正則寫在兩個反斜槓中間

    1. 反斜槓中間是表達式,修飾符緊跟在最後一個/後面

DEMO

// 實例化RegExp類定義
const reg = new RegExp("\\d",'g');

// 字面量//定義
const reg = /\d/g;

let str = "mmcai18is94a99boy";
let result = str.replace(reg," ")

console.log(str)
// 結果:mmcai18is94a99boy
console.log(result)
// 結果:mmcai is a body

// 字符串的replace方法不會修改原字符串,會返回一個新的字符串

修飾符

  • g:全文搜索,匹配到第一個就結束
  • i:忽略大小寫
  • m:多行搜索

對象屬性

  • global:對象是否具有標誌g;結果是布爾值
  • ignoreCase:對象是否具有標誌i;結果是布爾值
  • lastIndex:一個整數,標識開始下一次匹配的字符位置;結果是數字
  • multiline:對象是否具有標誌m;結果是布爾值
  • source:正則表達式的源文本;結果是字符串
let patt = /[a-z]\d/gim;

patt.global = true;
patt.ignoreCase = true;
patt.multiline = true;
patt.source = "[a-z]\d"

工作空間

其實這裏想要表達的是正則表達式可以在那些方法上使用;

應用場景可以分爲兩種情況

  1. 正則對象本身具有的一些方法

    1. test:檢索字符串中指定的值。返回true或false
    2. exec:檢索字符串中指定的值。找到返回數組,否則返回null
    3. compile:改變正則表達式,不常用
  2. 一些字符串操作方法當中

    1. String.replace:替換與正則表達式匹配的字符串
    2. String.search:檢索與正則表達式相匹配的值
    3. String.split:把字符串分割爲字符串數組
    4. String.match:找到一個或多個正則表達式的匹配

DEMO

// test 判斷字符串是否符合我們定義的規則
// 表單驗證的時候,可以使用test驗證:手機號,郵箱,身份證號碼,銀行卡等數據是否合法
let patt = /1[35789]\d{9}/;
let str = "13588322792"
let flag = patt.test(str);
console.log(flag);

// exec 當沒有全局修飾符的時候,函數的作用和match函數一樣,如果匹配到返回一個數組,否則返回null
// 把以下代碼放入編輯器,查看結果
var str="I love antzone ,this is animate";
var reg=/[a-z]{2}/;
var result = reg.exec(str);
console.log(result);

// result數組有至少兩個值,外加兩個屬性input和index
- result[0]:匹配的字符串
- result[1]:存放第一個分組匹配的值,否則爲undefined
- result[2]:存放第二個分組匹配的值,否則沒有改項
- result[n]:存放第n個分組匹配的值,否則沒有該項
result.index = 匹配字符串的索引
result.input = 要匹配字符串完整的引用


// exec 有全局修飾符g的時候,此函數返回值同樣是一個數組,並且也只能夠在字符串中匹配一次。不過此時,此函數一般會和lastIndex屬性匹配使用,此函數會在lastIndex屬性指定的字符處開始檢索字符串,當exec()找到與表達式相匹配的字符串時,在匹配後,它將lastIndex 屬性設置爲匹配字符串的最後一個字符的下一個位置。可以通過反覆調用exec()函數遍歷字符串中的所有匹配,當exec()函數再也找不到匹配的文本時,它將返回null,並把lastIndex 屬性重置爲0。
數組的內容結構和沒有g修飾符時完全相同。

var str="the name 123 and 456";
var reg=/\d/g;
reg.lastIndex=15;
console.log(reg.exec(str));

String.search

search不執行全局匹配,會忽略修飾符g。

如果匹配到,返回匹配值所在的索引,否則返回-1

var str="Visit W3School!"
var r = str.search(/w3school/);
console.log(r);

String.replace

返回一個新的字符串,是替換後得到的新值。

replace有兩個參數:

  • 第一個可以是字符串,也可以是正則表達式
  • 第二個可以是字符串,也可是function

如果第二個是字符串,字符串中的$字符有特定的含義

字符 說明
$1...$99 子表達式匹配的文本
$& 與regexp想匹配的字符串
$` 位於子匹配字符串左側的文本
$' 位於子表達式匹配內容右側的文本
$$ 直接量符號
1.簡單用法
var str="Visit Microsoft!"
var res = str.replace(/Microsoft/, "W3School");
console.log(res);

2.修飾符g,全局匹配
var str="Welcome to Microsoft! "
str=str + "We are proud to announce that Microsoft has "
str=str + "one of the largest Web Developers sites in the world."

var res = str.replace(/Microsoft/g, "W3School");
console.log(res);

3.修飾符i,忽略大小寫
var text = "javascript Tutorial";
var res = text.replace(/javascript/i, "JavaScript");
console.log(res)

4.字符中的$
var name = "Doe, John";
var res =  name.replace(/(\w+)\s*, \s*(\w+)/, "$2 $1");
console.log(res)

5.
var name = '"a", "b"';
var res = name.replace(/"([^"]*)"/g, "'$1'");

6.第二個參數是函數
var name = 'aaa bbb ccc';
var uw=name.replace(/\b\w+\b/g, function(word){
  return word.substring(0,1).toUpperCase()+word.substring(1);}
);

String.match

匹配到就返回一個數組,數組結構參考上面的exec方法,否則返回null

var str="Hello world!"
var res1 = str.match("world");
var res2 = str.match("World");
console.log(res1);
console.log(res2);


var str="1 plus 2 equal 3"
var res3 = str.match(/\d+/g);
console.log(res3);

String.split

把字符串分割成字符串數組。

返回一個字符串數組。

1.
var str="How are you doing today?"
var res1 = str.split(" ");
var res2 = str.split("");
var res3 = str.split(" ",3);

2.
var words = str.split(/\s+/)

3.
"hello".split("")

元字符

一般情況下,正則表達式的一個字符對應字符串的一個字符。
如果我們想要匹配一類的字符的時候,就可以通過元字符來處理,常用的元字符有:

代碼 說明
. 匹配除換行符以外的任意字符
w 匹配字母或數字或下劃線或漢字
s 匹配任意的空白符(包括空格,製表符(Tab),換行符,中文全角空格等)
d 匹配數字
b 匹配單詞的開始或結束
^ 匹配字符串的開始
$ 匹配字符串的結束

DEMO

1.匹配前後都是空格的字符串
let reg = /\b\w+\b/g;
let str = "my name is mmcai";
str.replace(reg,"xx");

2.修改時間格式2019 07 18爲2019/07/18
let reg = /\s/g;
let str = "2019 07 18";
str.replace(reg,"-");

3.匹配不是特殊符號的字符串
var str="Give 100%!";
var patt1=/\w/g;

4.匹配以Is開頭的字符串
var str="Is this his";
var patt1=/^Is/g;

5.對數字進行全局搜索
var str="Give 100%!";
var patt1=/\d/g;

6.對字符串結尾是is的進行匹配
var str="Is this his";
var patt1=/is$/g;

字符類&範圍類&字符轉義

要想查找數字,字母或數字,空白我們可以根據上面一節提到的元字符來匹配。但是如果想匹配的字符集合沒有預定義的元字符集合,怎麼辦?這時候我們就可以通過定義字符類類的形式進行匹配。

例如

[.?!]——匹配表單符號(.或?或!)
[abc]——匹配字符a或b或c
[aeiou]——匹配任何一個英文元音字母

除了以上方式,我們還可以通過-來指定一個字符範圍。

例如

[0-9]——匹配0到9的任意數字,含義和 \d 元字符一樣
[a-zA-Z]——匹配26個英文字符,大小寫都行

特點

  • 使用元字符[]來構建一個簡單的類
  • 使用-字符定義一個字符範圍
  • 所謂類就是符合某些特性的對象,一個泛指,不是指某個字符

DEMO

1.匹配開頭是a或b或c緊跟一個數字的字符
var reg =/[abc]\d/g;
var str = "a1b2c3d4";
str.replace(reg,"-");
// result = "---d4";

2.匹配a到h之間的字符
var str="Is this all there is?";
var patt1=/[a-h]/g;

字符轉義理解起來相對簡單,所謂的轉義其實是轉義我們的元字符,有時候我們需要匹配那些元字符本身的字符串,
就可以通過在元字符前面添加來進行轉義;

例如下面一些例子:

// 匹配元字符.
let reg = /\./;

// 匹配元字符/
let reg = /\//

//匹配元字符*
let reg = /\*/

//匹配字符類的[]
let reg = /\[\]/

// 匹配\本身
let reg = /\\/;

量詞

就是表示匹配的數量,我們可以通過一些限定符類指定匹配重複的數量

代碼 說明
  • | 重複0次或更多次
  • | 重複一次或更多次

? | 重複0次或一次
{n} | 重複n次
{n,} | 重複n次或更多次
{n,m} | 重複n到m次

DEMO

// 匹配window後面跟1個或多個數字的字符
let reg = /window\d+/;

// 匹配字符的第一個單詞
let reg = /^\w+/

//匹配時間格式爲YYYY-MM-DD的字符串
let reg = /\d{4}(-\d{2}){2}$/;
let str = "2019-07-18";

//爲了 避免匹配到"2019-07-1234124"這樣的字符串,添加$結尾符號
reg.test(str)

分支條件

有時候我們匹配的時候,規則不是單一的,可能有多個規則,我們就可以通過分支條件來實現。

比如,我們想要匹配固定電話,有些是三位區號,八位本地號,有些是四位區號,7位本地號,我們就可以如下寫:

let reg = /0\d{2}-\d{8}|0\d{3}-\d{7}/

DEMO

1. 匹配IP
let reg = /^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
let str = "192.168.0.253";
reg.test(str);

// 必須添加^,否則會匹配315.168.0.254這樣的字段中的15.168.0.254這一段

反義

反義就是取相反,例如d是匹配數字,D就是匹配不是數字的字符,s匹配空白符字符,S匹配不是空白符的字符。
在字符類中我們也可以使用^表示反義,1匹配除abc以外的字符,常見的反義代碼如下:

代碼 說明
W 匹配任意不是字母、數字、下劃線、漢字的字符
S 匹配任意不是空白符的字符
D 匹配任意不是數字的字符
B 匹配不是單詞開頭或結束位置的字符
2 匹配除x以外的任意字符
3 匹配除aeiou以外的任意字符

DEMO

參考匹配IP地址裏面,是如何匹配.這個元字符的

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