【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个数字的字符串
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章