【JavaScript正则表达式基础语法及案例】


前言

『勤学似春起之苗,不见其增,而日有所长』

这是个人学习时正则表达式基础语法时的案例笔记。
正则表达式是一种用于匹配字符串的模式,通过正则表达式创建匹配模式(规则)可以帮你完成指定​匹配。
在编程语言中,正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。
示例如无特殊说明,均指在javascript中测试。
如果对您有所帮助,烦请点赞收藏。


一、基础语法

1. test()方法

testRegex.test(testStr)方法会把编写的正则表达式和字符串(即括号内的内容)匹配,如果成功匹配到字符,则返回true,反之,返回false

var testStr = "【You are a genius!Genius。正则表达式测试1,3,75,100,章节一 哈哈yes,no】";
//单次模式匹配,找到一个就停止或返回
var testRegex = /are/; // 匹配are,注意, /are/ 不需要引号
var hasAre = testRegex.test(testStr); // 返回 true
console.log(testStr + " test()匹配 /are/:" + hasAre); // 在控制台中打印

2. match()方法

testStr.match(testRegex)​方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,返回指定的值

//match() ​方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,返回指定的值
testRegex = /Genius/i;
var result = testStr.match(testRegex); // match() ​方法
console.log(testStr + " match()匹配 /Genius/i:"+result);

3. 或 |

| 代表或,例如 yes|no 匹配yes或no

testRegex = /yes|no/;// | 代表或,匹配yes或no
console.log(testStr + " 或 | 匹配 /yes|no/:"+testRegex.test(testStr));

4. 忽略大小写 i

i 忽略大小写,例如 /Genius/i中的Genius任意大小写均可

testRegex = /Genius/i;// i 忽略大小写
console.log(testStr + " 忽略大小写 i 匹配 /Genius/i:"+testRegex.test(testStr));

5. 多次搜寻​或​提取模式匹配​ g

g 多次搜寻​或​提取模式匹配,例如 /Genius/g,返回多个匹配的值,没有g则匹配一个后停止

testRegex = /Genius/gi;
console.log(testStr + " 多次搜寻​或​提取模式 g 匹配 /Genius/gi:"+testStr.match(testRegex));

6. 通配符 .

.通配符,匹配任意字符。 例如 /Genius./ig 任意大小写 Genius后可以跟一个任意字符

testRegex = /Genius./ig;
console.log(testStr + " 通配符(匹配任何字符) . 匹配 /Genius./ig:"+testStr.match(testRegex));

7. 字符集 []

[] 字符集,在[]内的表示范围/集合,例如:[ab]表示匹配单个字符是a或b均可,

testRegex = /[Gg]enius/g;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " 字符集[]匹配 /[Gg]enius/g:"+result);

8. 连字符 -

- 连字符,表示集合的连接,例如 [a-z]表示a至z的字母,即所有小写字符,[A-Z]表示所有大写字符,[0-9]表示所有数字

testRegex = /[1-5]/g;
var result = testStr.match(testRegex); // match() ​方法
console.log(testStr + " 连字符 - 匹配 /[1-5]/g:"+result);

9. 否定字符集 [^]

[^] 否定字符集,在 []开始处加入^表示不包含后续的字符,例如[^a-z]表示不包含小写字母,[^1-5]表示不包含数字1至5

testRegex = /[^1-5]/g;
var result = testStr.match(testRegex); // match() ​方法
console.log(testStr + " 否定字符集 在[]中第一个加^[^1-5]匹配 /[^1-5]/g:"+result);

10. 匹配上限或下限 {n,m}

{n,m}匹配上限或下限,指定匹配的下限 {n,} 指定匹配的确切数量 {n},例如 a{2,3}匹配2个或3个a,a{2}匹配2个a,a{0,}匹配0个或多个a,相当于 a*a{1,}匹配至少一个a,相当于a+,a{0,1}匹配0个或1个a,相当于a?

var ohStr = "Ohhh no";
testRegex = /Oh{3,6}\sno/g; // 匹配3至6个h
console.log(ohStr + " 匹配的上限和下限 {n,m} 匹配 /Oh{3,6}\\sno/g:"+testRegex.test(ohStr));

11. 匹配0个或一个 ?

? 相当于 {0,1},例如a?匹配0个或1个a,相当于a{0,1}

var  testStr2 = "【Pat Past passt passst】";
testRegex = /Pas?t/ig;
console.log(testStr2 + " 0个或一个 ?或{0,1} 匹配 /Pas?t/ig:"+testStr2.match(testRegex));

12. 匹配1个或多个 +

+ 相当于 {1,},例如a+匹配1个或多个a,相当于a{1,}

testRegex = /Pas+t/ig;
console.log(testStr2 + " 出现一次或者连续多次 + 或 {1,}匹配 /Pas+t/ig:"+testStr2.match(testRegex));

13. 匹配0个或多个 *

* 相当于 {0,},例如a*匹配0个或多个a,相当于a{0,}

testRegex = /Pas*t/ig;
console.log(testStr2 + " 出现零次或多次 * 或 {0,} 匹配 /Pas*t/ig:"+testStr2.match(testRegex));

14. 贪婪(最大/最长)匹配及懒惰(最小/最短)匹配

默认是贪婪(最大/最长)匹配。
懒惰(最小/最短) 匹配 。
对 指定上下限的使用 ? 可以获取懒惰(最小/最短)匹配,否则是贪婪(最大/最长)匹配。
a+ 默认匹配 aaa 中的 aaa,而不是a或aa。使用?后a+?变成懒惰(最小/最短)匹配,即 a+? 懒惰匹配 aaa 中的 a,而不是aa或aaa。

var str = "【titanickd】";
var regex1 = /t[a-z]*i/;
var regex2 = /t[a-z]*?i/;
console.log(str + " 贪婪匹配(默认) /t[a-z]*i/:"+str.match(regex1));
console.log(str + " 懒惰?匹配 /t[a-z]*?i/:"+str.match(regex2));

15. 匹配开头 ^

^ 匹配开头,必须放在最前面且不能有其他字符如,例如/^Pa/表示匹配以Pa开头的结果

testRegex = /^Pas*t/ig;
console.log(testStr2 + " 开头 ^ 匹配 /^Pas*t/ig:"+testStr2.match(testRegex));

16. 匹配结尾 $

$ 匹配结尾,在表达式最后放$表示匹配结尾,例如/Pat$/表示匹配以Pat结尾的结果

testRegex = /Pas*t$/ig;
console.log(testStr2 + " 结尾 $ 匹配 /Pas*t$/ig:"+testStr2.match(testRegex));

17. 元字符

元字符是正则表达式中的专用字符,具有特殊的意义,用于匹配特定的字符或字符串,用于实现普通字符无法完成的功能。一般情况下,\大写字母相当于\非小写字母,例如\d相当于[0-9],\D相当于[^0-9],\w 相当于[A-Za-z0-9_],\W相当于[^A-Za-z0-9_],\s相当于 [\r\t\f\n\v] 空格、回车符、制表符、换页符和换行符查找空字符,即查找空白字符,\S相当于[^\r\t\f\n\v],\b 匹配单词边界, \B 匹配非单词边界,
\n匹配一个换行符。

//\d 等同于 [0-9] 匹配数字,
testRegex = /[a-z][A-z][\w]/g;
console.log(str + " 大小写字母加数字加下划线 \\w 或 [A-Za-z0-9_]匹配 /[a-z][A-z][\\w]/g:"+str.match(testRegex));
var numStr = "【106.23】";
testRegex = /\d/g;
console.log(numStr + " 数字 [0-9]或\\d 匹配 /\\d/g:"+numStr.match(testRegex));
//\D 等同于[^0-9]表示非数字 
testRegex = /\D/g;
console.log(numStr + " 非数字 [^0-9] [^\d] 匹配 /\\D/g:"+numStr.match(testRegex));

18. 先行断言 (?=…) (?!..)

先行断言的更实际用途是检查一个字符串中的两个或更多匹配模式,即查找是否满足要求但是不返回。
正向先行断言 (?=…) ,其中…就是需要存在但不会被匹配的部分。
负向先行断言 (?!..),其中…是希望不存在的匹配模式

var quit = "qu";
var noquit = "qt";
var quRegex= /q(?=u)/;
var qRegex = /q(?!u)/;
console.log(quit + " 正向先行断言 (?=...) 匹配 /q(?=u)/:"+quit.match(quRegex)); // 返回 ["q"]
console.log(noquit + " 负向先行断言 (?!...) 匹配 /q(?!u)/:"+noquit.match(qRegex)); // 返回 ["q"]
var password = "abc3ut";
testRegex = /(?=\w{3,6})(?=\D*\d)/;
console.log(password + " 正向先行断言 (?=...) 匹配 /(?=\\w{3,6})(?=\\D*\\d)/:"+testRegex.test(password));
console.log(password + " 正向先行断言 (?=...) 匹配 /(?=\\w{3,6})(?=\\D*\\d)/:"+password.match(testRegex));
//使用先行断言以匹配大于5个字符且有两个连续数字的密码,并且不能以数字开头 /^\D(?=\w{5,})(?=\w+\d{2,})/; 
//应该匹配 abc123,bana12,不该匹配astronaut 123 8pass99 12abcde
password = "bana12";
console.log(password + " 正向先行断言 (?=...) 匹配 /^\\D(?=\\w{5,})(?=\\w+\\d{2,})/:"+/^\D(?=\w{5,})(?=\w+\d{2,})/.test(password));

19. 捕获组 ()

() 捕获组,每个括号是一个捕获组,可以使用\m来重用捕获组,例如([a-z]+)([0-9]+)\1包含两个捕获组,分别是组1([a-z]+),组2([0-9]+),然后使用\1重用了捕获组1,实际相当于([a-z]+)([0-9]+)([a-z]+)

//括号 () 来检查字符组/捕获组   P(engu|umpk)in
str = "Eleanor Roosevelt";
//应该匹配 Franklin D. Roosevelt,Eleanor Roosevelt,不应该匹配Franklin Rosevelt
testRegex = /(Franklin|Eleanor).*Roosevelt$/;
console.log(str + " 括号来检查字符组/捕获组 () 匹配 /(Franklin|Eleanor).*Roosevelt$/:"+testRegex.test(str));
//捕获组重用模式 使用()包含的成为捕获组可以使用\+数字引用捕获组 \1
str = "42 42 42";
//应该匹配42 42 42,100 100 100,不应该匹配42 42, 42 42 42 42,101 102 103
testRegex = /^(\d+)\s\1\s\1$/;
console.log(str + " 捕获组重用(m从1开始) \\m 匹配 /^(\\d+)\\s\\1\\s\\1$/:"+testRegex.test(str));

20. 搜索并替换 replace()

str.replace(Regex,ReplaceString) 搜索并替换,例如"sky".replace(\sky\,"sun")表示搜索sky并用sun替换。
可以使用 $m替换捕获组m

//搜索并替换 .replace(Regex,ReplaceString) 
str = "The sky is silver.";
testRegex = /silver/;
console.log(str + " 搜索并替换 str.replace(Regex,ReplaceString) 匹配 /silver/:"+str.replace(testRegex,"blue"));
//使用美元符号($)访问替换字符串中的捕获组
testRegex = /(\w+)\s(\w+)/;
console.log(str + " 访问捕获组(n从1开始) 使用 $n 匹配 str.replace(/(\\w+)\\s(\\w+)/,'$2 $1')搜索并替换  匹配 /silver/:"+str.replace(testRegex,'$2 $1'));

二. javascript案例

以下是基础语法的全部案例及一些扩展。

<!DOCTYPE html>
<html>
<head>
    <!--字符编码-->
    <meta charset='utf-8'>
    <!--文件头,用于解析,http-equiv 键,content值-->
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <!--设置标题-->
    <title>Regex Test</title>
    <!--网页在移动设备上会根据设备宽度自适应调整布局和大小-->
    <meta name='viewport' content='width=device-width, initial-scale=1'>
    <!--引入样式-->
    <!--<link rel='stylesheet' type='text/css' media='screen' href='regex.css'>-->
    <!--引入js-->
    <!--<script src='regex.js'></script>-->
    <!--内部js-->
    <script >
        var testStr = "【You are a genius!Genius。正则表达式测试1,3,75,100,章节一 哈哈yes,no】";
        //单次模式匹配,找到一个就停止或返回
        var testRegex = /are/; // 匹配are,注意, /are/ 不需要引号
        var hasAre = testRegex.test(testStr); // 返回 true
        console.log(testStr + " test()匹配 /are/:" + hasAre); // 在控制台中打印

        testRegex = /yes|no/;// | 代表或,匹配yes或no
        console.log(testStr + " 或 | 匹配 /yes|no/:"+testRegex.test(testStr));

        testRegex = /Genius/i;// i 忽略大小写
        console.log(testStr + " 忽略大小写 i 匹配 /Genius/i:"+testRegex.test(testStr));

        //match() ​方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,返回指定的值
        testRegex = /Genius/i;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " match()匹配 /Genius/i:"+result);

        //多次搜寻​或​提取模式匹配​,可以使用g
        testRegex = /Genius/gi;
        console.log(testStr + " 多次搜寻​或​提取模式 g 匹配 /Genius/gi:"+testStr.match(testRegex));

        //通配符. 匹配任何字符
        testRegex = /Genius./ig;
        console.log(testStr + " 通配符(匹配任何字符) . 匹配 /Genius./ig:"+testStr.match(testRegex));
    
        //字符集 []
        testRegex = /[Gg]enius/g;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " 字符集[]匹配 /[Gg]enius/g:"+result);

        //字符集 []及连字符-,例如a-c,1-5
        testRegex = /[1-5]/g;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " 连字符 - 匹配 /[1-5]/g:"+result);

        //1-200之间 ^([1-9]|[1-9]\d|1\d{2}|200)$
        testRegex = /([1-9]|[1-9]\d|1\d{2}|200)/g;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " 数字匹配 [0-9]或\\d匹配 /([1-9]|[1-9]\\d|1\\d{2}|200)/g:"+result);

        //否定字符集,在开始括号后面和不想匹配的字符前面放置插入字符(即^) [^1-5]
        testRegex = /[^1-5]/g;
        var result = testStr.match(testRegex); // match() ​方法
        console.log(testStr + " 否定字符集 在[]中第一个加^[^1-5]匹配 /[^1-5]/g:"+result);

        //? 匹配0个或一个 {0,1}
        var  testStr2 = "【Pat Past passt passst】";
        testRegex = /Pas?t/ig;
        console.log(testStr2 + " 0个或一个 ?或{0,1} 匹配 /Pas?t/ig:"+testStr2.match(testRegex));
        // + 匹配出现一次或者连续多次的的字符
        testRegex = /Pas+t/ig;
        console.log(testStr2 + " 出现一次或者连续多次 + 或 {1,}匹配 /Pas+t/ig:"+testStr2.match(testRegex));
        //* ​可以匹配出现零次或多次的字符
        testRegex = /Pas*t/ig;
        console.log(testStr2 + " 出现零次或多次 * 或 {0,} 匹配 /Pas*t/ig:"+testStr2.match(testRegex));
        //默认贪婪(最大/最长)匹配,可以使用 ? 懒惰(最小/最短)匹配
        var str = "【titanickd】";
        var regex1 = /t[a-z]*i/;
        var regex2 = /t[a-z]*?i/;
        console.log(str + " 贪婪匹配(默认) /t[a-z]*i/:"+str.match(regex1));
        console.log(str + " 懒惰?匹配 /t[a-z]*?i/:"+str.match(regex2));

        //^ 在最开始匹配开头 
        testRegex = /^Pas*t/ig;
        console.log(testStr2 + " 开头 ^ 匹配 /^Pas*t/ig:"+testStr2.match(testRegex));
        
        //$ 在最后匹配结尾 
        testRegex = /Pas*t$/ig;
        console.log(testStr2 + " 结尾 $ 匹配 /Pas*t$/ig:"+testStr2.match(testRegex));
        
        //元字符 \w 等同于[A-Za-z0-9_] [a-z]匹配所有小写字母 [A-Z]匹配所有大写字母 
        testRegex = /[a-z][A-z][\w]/g;
        console.log(str + " 大小写字母加数字加下划线 \\w 或 [A-Za-z0-9_]匹配 /[a-z][A-z][\\w]/g:"+str.match(testRegex));

        //\d 等同于 [0-9] 匹配数字,
        var numStr = "【106.23】";
        testRegex = /\d/g;
        console.log(numStr + " 数字 [0-9]或\\d 匹配 /\\d/g:"+numStr.match(testRegex));
        //\D 等同于[^0-9]表示非数字 
        testRegex = /\D/g;
        console.log(numStr + " 非数字 [^0-9] [^\d] 匹配 /\\D/g:"+numStr.match(testRegex));

        //\w 等同于[A-Za-z0-9_] 查找非单词字符 \W 查找非单词字符
        //\d 等同于[0-9] 查找数字 \D 查找非数字
        //\s 等同于 [\r\t\f\n\v] 空格、回车符、制表符、换页符和换行符查找空字符  \S 查找非空格字符
        //\b 匹配单词边界 \B 匹配非单词边界\
        //\0 匹配一个NUL字符 
        //\n 匹配一个换行符
        //\xxx 匹配字符的八进制转义值
        //\xdd 查找以16进制dd规定的字符

// 1) 用户名只能是数字字母字符。
// 2) 用户名中的数字必须在最后,且数字可以有零个或多个。
// 3) 用户名字母可以是小写字母和大写字母。
// 4) 用户名长度必须至少为两个字符
// 5) 匹配值JACK Jo Oceans11 RegexGuru Z97,不应该匹配 J 007 9 A1 BadUs3rnam3 c57bT3
// 注意:^[a-zA-Z]+([a-zA-Z] | [0-9])$不能匹配JO: 
// 虽然 "J" 满足了 [a-zA-Z]+ 的条件,但是在 "J" 后面的 "O" 并不被视为是额外的字母或数字,因为它仍然是字母序列的一部分。   
// 所以,"JO" 不满足正则表达式的要求,因为它没有在字母序列之后紧跟着一个额外的字母或数字 
        var JO = "JO";
        testRegex = /^[a-zA-Z](\d{2,}|[a-zA-Z]+\d*)$/i;
        //testRegex = /^[a-z]([0-9]{2,}|[a-z]+\d*)$/i;
        console.log(JO + " 混合 匹配 /^[a-zA-Z](\\d{2,}|[a-zA-Z]+\\d*)$/i:"+testRegex.test(JO));
        
        //指定匹配的上限和下限 {n,m}  指定匹配的下限 {n,} 指定匹配的确切数量 {n}
        //? 相当于 {0,1}
        //+ 相当于 {1,}
        //* 相当于 {0,}
        //匹配在"Oh no"中仅出现3到6次的字母h
        var ohStr = "Ohhh no";
        testRegex = /Oh{3,6}\sno/g; // 
        console.log(ohStr + " 匹配的上限和下限 {n,m} 匹配 /Oh{3,6}\\sno/g:"+testRegex.test(ohStr));

        //先行断言的更实际用途是检查一个字符串中的两个或更多匹配模式
        //正向先行断言 (?=...)  其中...就是需要存在但不会被匹配的部分
        //负向先行断言 (?!...),其中...是希望不存在的匹配模式
        var quit = "qu";
        var noquit = "qt";
        var quRegex= /q(?=u)/;
        var qRegex = /q(?!u)/;
        console.log(quit + " 正向先行断言 (?=...) 匹配 /q(?=u)/:"+quit.match(quRegex)); // 返回 ["q"]
        console.log(noquit + " 负向先行断言 (?!...) 匹配 /q(?!u)/:"+noquit.match(qRegex)); // 返回 ["q"]
        var password = "abc3ut";
        testRegex = /(?=\w{3,6})(?=\D*\d)/;
        console.log(password + " 正向先行断言 (?=...) 匹配 /(?=\\w{3,6})(?=\\D*\\d)/:"+testRegex.test(password));
        console.log(password + " 正向先行断言 (?=...) 匹配 /(?=\\w{3,6})(?=\\D*\\d)/:"+password.match(testRegex));

        //使用先行断言以匹配大于5个字符且有两个连续数字的密码,并且不能以数字开头 /^\D(?=\w{5,})(?=\w+\d{2,})/; 
        //应该匹配 abc123,bana12,不该匹配astronaut 123 8pass99 12abcde
        password = "bana12";
        console.log(password + " 正向先行断言 (?=...) 匹配 /^\\D(?=\\w{5,})(?=\\w+\\d{2,})/:"+/^\D(?=\w{5,})(?=\w+\d{2,})/.test(password));
    
        //括号 () 来检查字符组   P(engu|umpk)in
        str = "Eleanor Roosevelt";
        //应该匹配 Franklin D. Roosevelt,Eleanor Roosevelt,不应该匹配Franklin Rosevelt
        testRegex = /(Franklin|Eleanor).*Roosevelt$/;
        console.log(str + " 括号来检查字符组/捕获组 () 匹配 /(Franklin|Eleanor).*Roosevelt$/:"+testRegex.test(str));

        //捕获组重用模式 使用()包含的成为捕获组可以使用\+数字引用捕获组 \1
        str = "42 42 42";
        //应该匹配42 42 42,100 100 100,不应该匹配42 42, 42 42 42 42,101 102 103
        testRegex = /^(\d+)\s\1\s\1$/;
        console.log(str + " 捕获组重用(n从1开始) \\n 匹配 /^(\\d+)\\s\\1\\s\\1$/:"+testRegex.test(str));

        //搜索并替换 .replace(Regex,ReplaceString) 
        str = "The sky is silver.";
        testRegex = /silver/;
        console.log(str + " 搜索并替换 str.replace(Regex,ReplaceString) 匹配 /silver/:"+str.replace(testRegex,"blue"));
        //使用美元符号($)访问替换字符串中的捕获组
        testRegex = /(\w+)\s(\w+)/;
        console.log(str + " 访问捕获组(n从1开始) 使用 $n 匹配 str.replace(/(\\w+)\\s(\\w+)/,'$2 $1')搜索并替换  匹配 /silver/:"+str.replace(testRegex,'$2 $1'));

        //删除字符串开头和结尾处的空格 .trim()方法在这里也可以实现同样的效果
        str = "   Hello, World!  ";
        testRegex = /^(\s+)(.+\S)(\s+)$/; 
        console.log(str + " 删除字符串开头和结尾处的空格 str.replace(/^(\\s+)(.+\\S)(\\s+)$/,'$2')搜索并替换 匹配 /silver/:"+str.replace(testRegex,'$2'));
    
        //匹配邮箱地址 2954@qq.com,dai,daiho@cr-leasing.com.cn,@.com
        str = "我的邮箱地址是2954@qq.com,dai,daiho@cr-leasing.com.cn,@.com"
        testRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;// /\w+@[\w-]\.[a-zA-Z]+(?=[])/g;
        console.log(str + " 邮箱地址 匹配 //g:"+str.match(testRegex));

        

    </script>
</head>
<body>
   
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不忘初心,牢记使命

善心生善果,善语结善缘。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值