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>