【JS】正則表達式

前言

之前學過python的正則表達式,沒怎麼學懂,但是既然都是正則表達式學哪個語言應該沒有什麼區別纔是(

先寫個例子看看正則表達式是什麼!

用VS Code打開一個文件夾,新建一個module.html文件,把.vscode文件夾下的launch.json文件設置爲

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "file:///C:/Users/LX/Desktop/Code/JSLearning/module.html",
            "webRoot": "${workspaceRoot}"
        }
    ]
}

路徑按自己建的位置來。再新建一個regularExpression.js文件,寫入

var reg=/(\w+):\/\/([\w.]+)\/(\S*)/;
var text="Visit my blog at http://www.example.com/~david";
var result=text.match(reg);
if(result!=null){
    var myUrl=result[0];
    var myProtocol=result[1];
    var myHost=result[2];
    var myPath=result[3];

}

console.log("url = ",myUrl);                // http:www.example.com/~david
console.log("protocol = ",myProtocol);      //http               <-  (\w+)
console.log("host = ",myHost);              //www.example.com    <-  ([\w.]+)
console.log("path = ",myPath);              //~david             <-  (\S*) 
console.log("local search result is ",result);//["http://www.example.com/~david", "http", "www.example.com", "~david"]
console.log("global search result is ",text.match(/(\w+):\/\/([\w.]+)\/(\S*)/g));// ["http://www.example.com/~david"]
console.log(RegExp(reg,"g"));
  • 用sublime text的話很方便,畢竟這些代碼都是給遊覽器執行的,VSCode竟然這麼麻煩實在浪費時間。在sublime Text中的html文件內右擊在遊覽器內打開就行,VSCode中也有這個選項但是我一直弄不出效果233。

module.html寫入下面的代碼——這個文件在學習時就不用改太多了

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>

		<!--
			註釋
		-->

        <script type='text/javascript' src='regularExpression.js'></script>
        <script type='text/javascript'>
    
        </script>
    </head>
    <body>

    </body>
</html>

運行結果在js文件註釋裏。有了這個例子,大家也就明白了,就算你還沒了解正則表達式的的偉大,你也知道了這個技術可以把url提取出來。對於想做爬蟲的我,知道這點就明白了,必須學懂這個。

  • 下面的代碼都直接寫入regularExpression.js這個文件內運行,或者在遊覽器或VS Code的console端運行都可以—— clear() 命令可以清空console端

普通的字面量匹配

正則表達式在JS中是以斜杆爲邊界形式存在的。

console.log("JavaScript have much fun".match(/JavaScript/));

運行結果
在這裏插入圖片描述
這種程度的匹配是最簡單的,但是問題是太侷限了。必須把整個單詞拼得一字不差才行。你也許會想,對於這個匹配JavaScript的,這個字符串中這個單詞是第一個,後面還有空格,我只要找到空格就行了對吧!雖然可以實現,但是這樣的方式實在是太麻煩了!

爲了偷懶,於是正則表達式誕生了。(對別的技術也是這樣)

字符 匹配
[…] 滿足方框內條件的任意字符
[^…] 不滿足方框內條件的任意字符
. (一個點) 除換行符和其他Unicode行終止符的任意字符
\w 任意ASCII字符,等價於 [a-zA-Z0-9]
\W 任意不是ASCII字符的字符,等價於[^a-zA-Z0-9]
\s 任何Unicode空白字符
\S 任何非Unicode空白符的字符
\d 任何ASCII數字,等價於[0-9]
\D 任何不是ASCII數字的字符,等價於[^0-9]
[\b] 退格(特例)
{s,e} 匹配前一項至少s次,最多m次
{s,} 匹配前一項至少s次
{s} 匹配前一項s次
? 匹配前一項0次或1次,等價於{0,1}
+ 匹配前一項至少1次,等價於{1,}
* 匹配前一項至少0次 ,等價於{0,}

現在來測試一下
下面這個例子中,匹配了數字 1 2 3。第一個只匹配了第一個數字1,第二個區別是在正則表達式後面加了修飾符g,表示全局的 —— 用 .global()方法可以返回這個正則表達式是否有g修飾符。
在這裏插入圖片描述

正則表達式修飾符 含義
i 執行不區分大小寫的匹配
g 執行全局匹配
m 執行多行匹配。
var pattern=/Java/gi;
var text="JavaScript is more fun than java!";
var result;
while(result=pattern.exec(text)){
    console.log(
        "Matched '"+result[0]+"'"
        +" at position "+result.index +
        "; next search begins at "+pattern.lastIndex
    );
}

運行結果

Matched 'Java' at position 0; next search begins at 4
Matched 'java' at position 28; next search begins at 32

貪婪模式與非貪婪模式

匹配多次的匹配符都是貪婪的,有時處理字符串並不需要匹配所有滿足添加的字符,只需要匹配部分,這時候就需要在該項後面加上 ? —— 但是這個也不一定滿足條件,一般可以先試試。

可選、分組和引用

字符 含義
豎槓 可選,匹配該符號的左邊子表達式或右表達式
(…) 組合,將幾個字符合成一個單元,可以對這個單元進行 * + ?等操作。還能記住這個組合相匹配的字符串以供後面引用
(?:…) 只進行組合
\n 和組合一起用。用左括號做索引數n,用\n就可以代表該組合。
var a="'JavaScript\"er";
var b=/['"][^'"]*['"]/;
console.log(a.match(b));

運行結果

'JavaScript'

明明這個單詞左右的引號不同,但是還是被匹配出來了。如果我需要左右匹配相同的引號的話,需要使用\n

var a="'JavaScript'er";
var b=/(['"])[^'"]*\1/;
console.log(a.match(b));

運行結果

'JavaScript'

可以發現,如果組合起來就可以保存被匹配的字符,在之後用\n引用時,這個保存的字符就會有作用。這裏的作用就是使匹配的左右引號相同。

  \;
  \;
  \;

search()|replace()|match()|exec()|test()

search()參數是正則表達式。返回第一個與之匹配的字符串子串的起始位置,並且這個方法不支持g修飾符,會忽略g。

"JavaScript is not java".search(/java/gi); //0

replace()第一個參數是正則表達式,第二個是要替換的字符串。

"HHHHHhhhhhHHHHH".replace(/[H]+h/,"@");  //@hhhhHHHHH

match()參數是正則表達式。如果正則表達式是全局的,那麼其返回一個數組,元素是各個匹配到的子串,如果不是全局的,那麼也返回一個數組,第一個元素(比如a[0])是匹配到的子串,其他是匹配相應括號的子串(比如a[1]是滿足第一個括號匹配的子串)

這個例子前面有,這裏再寫一遍

var reg=/(\w+):\/\/([\w.]+)\/(\S*)/;
var text="Visit my blog at http://www.example.com/~david";
var result=text.match(reg);
if(result!=null){
    var myUrl=result[0];
    var myProtocol=result[1];
    var myHost=result[2];
    var myPath=result[3];

}

console.log("url = ",myUrl);                // http:www.example.com/~david
console.log("protocol = ",myProtocol);      //http               <-  (\w+)
console.log("host = ",myHost);              //www.example.com    <-  ([\w.]+)
console.log("path = ",myPath);              //~david             <-  (\S*) 
console.log("local search result is ",result);//["http://www.example.com/~david", "http", "www.example.com", "~david"]
console.log("global search result is ",text.match(/(\w+):\/\/([\w.]+)\/(\S*)/g));// ["http://www.example.com/~david"]

exec()參數和match()一樣。每次執行match()時,返回的正則表達式對象的lastIndex不變,而exec()執行後每次lastIndex都是匹配的最後位置,如果exec匹配不到也會把lastIndex置零。


var pattern=/Java/gi;
var text="JavaScript is more fun than java!";
var result;
while(result=pattern.exec(text)){
    console.log(
        "Matched '"+result[0]+"'"
        +" at position "+result.index +
        "; next search begins at "+pattern.lastIndex
    );
}

console.log(pattern.lastIndex); //0

test()參數是一個字符串。只返回真假。

var pattern=/java/i;
pattern.test("Javascript") ;//true

  \;
  \;

RegExp對象

前面講的有些函數就行RegExp對象的方法,這個對象的構造函數有兩個參數。第一個是正則表達式的字符串(在這個字符串中,原來正則表達式裏的反斜槓,在這裏就要寫成兩個反斜槓,畢竟是字符串傳遞進去的嘛),第二個參數是可選的修飾符,比如

var a=new RegExp("\\d{5}","g");//全局搜索,有連續5個數字的字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章