正则表达式
正则表达式
https://www.runoob.com/js/js-regexp.html
1.什么是正则表达式?
正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。
此外,正则表达式还常用于过滤掉页面内容中的一些敏感词(替换),或从字符串中获取我们想要的特定部分(提取)等
语法
var patt = /runoob/i
/正则表达式主体/修饰符(可选)
正则表达式修饰符
修饰符 可以在全局搜索中不区分大小写:
| 修饰符 | 描述 |
|---|---|
| i | 执行对大小写不敏感的匹配。 |
| g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
| m | 执行多行匹配。 |
| gi | 全局匹配 并且 对大小写不敏感 |
2.正则表达式在js中的使用
2.1正则表达式的创建
在 JavaScript 中,可以通过两种方式创建一个正则表达式。
方式一:通过调用RegExp对象的构造函数创建
var regexp = new RegExp(/123/);
console.log(regexp);
方式二:利用字面量创建 正则表达式
var rg = /123/;
2.2测试正则表达式
test() 正则对象方法,用于检测字符串是否符合该规则,该对象会返回 true 或 false,其参数是测试字符串。
regexObj.test(str)
- regexObj 是写的正则表达式
- str 是我们要测试的文本
var rg = /123/;
console.log(rg.test(123));//匹配字符中是否出现123 出现结果为true
console.log(rg.test('abc'));//匹配字符中是否出现123 未出现结果为false
| 方法 | 描述 |
|---|---|
| exec | 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。 |
| test | 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。 |
| match | 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。 |
| matchAll | 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。 |
| search | 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
| replace | 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
| split | 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。 |
3.正则表达式中的特殊字符
3.1正则表达式的组成
简单字符+特殊字符(元字符)
一个正则表达式可以由简单的字符构成,比如 /abc/,也可以是简单和特殊字符的组合,比如/ab*c/。其中特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号,如^、$ 、+ 等。
可以参考: MDN
jQuery 手册:正则表达式部分 https://www.jq22.com/chm/jquery/regexp.html
| 字符 | 描述 |
|---|---|
| \ | 将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。例如,“n”匹配字符“n”。“\n”匹配一个换行符。串行“\\”匹配“\”而“\(”则匹配“(”。 |
^ | 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。 |
$ | 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。 |
* | 匹配前面的子表达式零次或多次。例如,zo*能匹配“z”以及“zoo”。*等价于{0,}。 |
+ | 匹配前面的子表达式一次或多次。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。 |
? | 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“does”或“does”中的“do”。?等价于{0,1}。 |
{n} | n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。 |
{n,} | n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。 |
{n,m} | m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。 |
| ? | 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。 |
| . | 匹配除“\n”之外的任何单个字符。要匹配包括“\n”在内的任何字符,请使用像“`(. |
3.2边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
| 边界符 | 说明 |
|---|---|
^ | 表示匹配行首的文本(以谁开始) |
$ | 表示匹配行尾的文本(以谁结束) |
如果 ^和 $ 在一起,表示必须是精确匹配。
var rg = /abc/; // 正则表达式里面不需要加引号 不管是数字型还是字符串型
// /abc/ 只要包含有abc这个字符串返回的都是true
console.log(rg.test('abc'));
console.log(rg.test('abcd'));
console.log(rg.test('aabcd'));
console.log('---------------------------');
var reg = /^abc/;
console.log(reg.test('abc')); // true
console.log(reg.test('abcd')); // true
console.log(reg.test('aabcd')); // false 应为需要 abc 开头
console.log('---------------------------');
var reg1 = /^abc$/; // 精确匹配 要求必须是 abc字符串才符合规范
console.log(reg1.test('abc')); // true
console.log(reg1.test('abcd')); // false
console.log(reg1.test('aabcd')); // false 因为需要 abc结尾
console.log(reg1.test('abcabc')); // false 因为需要 abc结尾
3.3字符类
字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内。
3.3.1 [] 方括号
表示有一系列字符可供选择,只要匹配其中一个就可以了
/[abc]/ [a-z] /^[a-zA-Z0-9]$/
/^[^a-zA-Z0-9]$/ : 取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var rg = /[abc]/; // 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(rg.test('andy'));//true
console.log(rg.test('baby'));//true
console.log(rg.test('color'));//true
console.log(rg.test('red'));//false
var rg1 = /^[abc]$/; // 三选一 只有是a 或者是 b 或者是c 这三个字母才返回 true *****************三选一
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//false
----------------------------------------------------------------------------------
var reg = /^[a-z]$/ //26个英文字母任何一个字母返回 true - 表示的是a 到z 的范围
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false
-----------------------------------------------------------------------------------
//字符组合
var reg1 = /^[a-zA-Z0-9]$/; // 26个英文字母(大写和小写都可以)任何一个字母返回 true
------------------------------------------------------------------------------------
//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true
3.3.2量词符
量词符用来设定某个模式出现的次数。
| 量词 | 说明 |
|---|---|
* | >=0 重复0次或更多次 |
+ | >=1 重复1次或更多次 |
? | `1 |
{n} | 重复n次 |
{n,} | >=n重复n次或更多次 |
{n,m} | >=n && <=m重复n到m次 |
3.3.3用户名表单验证
功能需求:
- 如果用户名输入合法, 则后面提示信息为: 用户名合法,并且颜色为绿色
- 如果用户名输入不合法, 则后面提示信息为: 用户名不符合规范, 并且颜色为红色

分析:
- 用户名只能为英文字母,数字,下划线或者短横线组成, 并且用户名长度为6~16位.
- 首先准备好这种正则表达式模式
/$[a-zA-Z0-9-_]{6,16}^/ - 当表单失去焦点就开始验证.
- 如果符合正则规范, 则让后面的span标签添加 right类.
- 如果不符合正则规范, 则让后面的span标签添加 wrong类.
<input type="text" class="uname"> <span>请输入用户名</span>
<script>
// 量词是设定某个模式出现的次数
var reg = /^[a-zA-Z0-9_-]{6,16}$/; // 这个模式用户只能输入英文字母 数字 下划线 中划线
var uname = document.querySelector('.uname');
var span = document.querySelector('span');
uname.onblur = function() {
if (reg.test(this.value)) {
console.log('正确的');
span.className = 'right';
span.innerHTML = '用户名格式输入正确';
} else {
console.log('错误的');
span.className = 'wrong';
span.innerHTML = '用户名格式输入不正确';
}
}
</script>
3.3.4 括号总结
1.大括号 量词符. 里面表示重复次数
2.中括号 字符集合。匹配方括号中的任意字符.
3.小括号表示优先级
var reg = /^abc{3}$/ ; // 它是让c重复三次 abccc
var reg = /^(abc){3}$/ ; // 它是让abc重复三次
3.4预定义类
预定义类指的是某些常见模式的简写方式.
| 预定义类 | 说明 |
|---|---|
\d | 匹配0-9之间任意数字,相当于[0-9] |
\D | 匹配所有0-9以外任意字符,相当于[^0-9] |
\w | 匹配任意字母、数字和下划线,相当于[A-Za-z0-9_] |
\W | 匹配除所有字母、数字和下划线以外的任意字符,相当于[^A-Za-z0-9_] |
\s | 匹配空格(包括换行符、制表符、空格等),相当于[\t\r\n\v\f] |
\S | 匹配除非空格的字符,相当于[^\t\r\n\v\f] |
// 座机号码验证: 全国座机号码 两种格式: 010-12345678 或者 0530-1234567
var reg = /^\d{3}-\d{8}|\d{4}-\d{7}$/;// 正则里面的或者 符号 |
var reg = /^\d{3,4}-\d{7,8}$/;
4 正则替换replace
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
var str = 'andy和red';
var newStr = str.replace('andy', 'baby');
console.log(newStr)//baby和red
//等同于 此处的andy可以写在正则表达式内
var newStr2 = str.replace(/andy/, 'baby');
console.log(newStr2)//baby和red
//全部替换
var str = 'abcabc'
var nStr = str.replace(/a/,'哈哈')
console.log(nStr) //哈哈bcabc
//全部替换g
var nStr = str.replace(/a/g,'哈哈')
console.log(nStr) //哈哈bc哈哈bc
//忽略大小写i
var str = 'aAbcAba';
var newStr = str.replace(/a/gi,'哈哈')//"哈哈哈哈bc哈哈b哈哈"
案例:过滤敏感词汇
<textarea name="" id="message"></textarea> <button>提交</button>
<div></div>
<script>
var text = document.querySelector('textarea');
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.onclick = function() {
div.innerHTML = text.value.replace(/激情|gay/g, '**');
}
</script>
5. 正则表达式的方法
正则表达式可以被用于 RegExp 的 exec 和 test 方法以及 String 的 match、replace、search 和 split 方法。
| 方法 | 描述 |
|---|---|
| exec | 一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回 null)。 |
| test | 一个在字符串中测试是否匹配的RegExp方法,它返回 true 或 false。 |
| match | 一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。 |
| matchAll | 一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。 |
| search | 一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。 |
| replace | 一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。 |
| split | 一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。 |
常用正则表达式
https://c.runoob.com/front-end/854/
一、校验数字的表达式
- 数字:
^[0-9]*$ - n位的数字:
^\d{n}$ - 至少n位的数字:
^\d{n,}$ - m-n位的数字:
^\d{m,n}$ - 零和非零开头的数字:
^(0|[1-9][0-9]*)$ - 非零开头的最多带两位小数的数字:
^([1-9][0-9]*)+(\.[0-9]{1,2})?$ - 带1-2位小数的正数或负数:
^(\-)?\d+(\.\d{1,2})$ - 正数、负数、和小数:
^(\-|\+)?\d+(\.\d+)?$ - 有两位小数的正实数:
^[0-9]+(\.[0-9]{2})?$ - 有1~3位小数的正实数:
^[0-9]+(\.[0-9]{1,3})?$ - 非零的正整数:
^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$ - 非零的负整数:
^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$ - 非负整数:
^\d+$ 或 ^[1-9]\d*|0$ - 非正整数:
^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$ - 非负浮点数:
^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ - 非正浮点数:
^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ - 正浮点数:
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$ - 负浮点数:
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$ - 浮点数:
^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
二,校验字符的表达式
- 汉字:
^[\u4e00-\u9fa5]{0,}$ - 英文和数字:
^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$ - 长度为3-20的所有字符:
^.{3,20}$ - 由26个英文字母组成的字符串:
^[A-Za-z]+$ - 由26个大写英文字母组成的字符串:
^[A-Z]+$ - 由26个小写英文字母组成的字符串:
^[a-z]+$ - 由数字和26个英文字母组成的字符串:
^[A-Za-z0-9]+$ - 由数字、26个英文字母或者下划线组成的字符串:
^\w+$ 或 ^\w{3,20}$ - 中文、英文、数字包括下划线:
^[\u4E00-\u9FA5A-Za-z0-9_]+$ - 中文、英文、数字但不包括下划线等符号:
^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$ - 可以输入含有
^%&',;=?$\"等字符:[^%&',;=?$\x22]+ - 禁止输入含有~的字符:
[^~]+
三、特殊需求表达式
Email地址:
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$域名:
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?InternetURL:
[a-zA-z]+://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$手机号码:
^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):
^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$国内电话号码(0511-4405222、021-87888822):
\d{3}-\d{8}|\d{4}-\d{7}电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号):
((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)身份证号(15位、18位数字),最后一位是校验位,可能为数字或字符X:
(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):
^[a-zA-Z][a-zA-Z0-9_]{4,15}$密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):
^[a-zA-Z]\w{5,17}$强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在 8-10 之间):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$强密码(必须包含大小写字母和数字的组合,可以使用特殊字符,长度在8-10之间):
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$日期格式:
^\d{4}-\d{1,2}-\d{1,2}一年的12个月(01~09和1~12):
^(0?[1-9]|1[0-2])$一个月的31天(01~09和1~31):
^((0?[1-9])|((1|2)[0-9])|30|31)$钱的输入格式:
xml文件:
^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$中文字符的正则表达式:
[\u4e00-\u9fa5]双字节字符:
[^\x00-\xff](包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))空白行的正则表达式:
\n\s*\r(可以用来删除空白行)HTML标记的正则表达式:
<(\S*?)[^>]*>.*?|<.*? />( 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$)(可以用来删除行首行尾的空白字符(包空格、制表符、换页符等等),非常有用的表达式)腾讯QQ号:
[1-9][0-9]{4,}(腾讯QQ号从10000开始)中国邮政编码:
[1-9]\d{5}(?!\d)(中国邮政编码为6位数字)IPv4地址:
((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}
表单规则的正则:
在使用RegularExpressionValidator验证控件时的验证功能及其验证表达式介绍如下:
只能输入数字:“^[0-9]*$"
只能输入n位的数字:“^d{n}$"
只能输入至少n位数字:“^d{n,}$"
只能输入m-n位的数字:“^d{m,n}$"
只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$"
只能输入有两位小数的正实数:“^[0-9]+(.[0-9]{2})?$"
只能输入有1-3位小数的正实数:“^[0-9]+(.[0-9]{1,3})?$"
只能输入非零的正整数:“^+?[1-9][0-9]*$"
只能输入非零的负整数:“^-[1-9][0-9]*$"
只能输入长度为3的字符:“^.{3}$"
只能输入由26个英文字母组成的字符串:“^[A-Za-z]+$"
只能输入由26个大写英文字母组成的字符串:“^[A-Z]+$"
只能输入由26个小写英文字母组成的字符串:“^[a-z]+$"
只能输入由数字和26个英文字母组成的字符串:“^[A-Za-z0-9]+$"
只能输入由数字、26个英文字母或者下划线组成的字符串:“^w+$"
验证用户密码:“^[a-zA-Z]w{5,17}$"正确格式为:以字母开头,长度在6-18之间,
输入框的值校验
利用正则表达式限制网页表单里的文本框输入内容
用正则表达式限制只能输入中文:onkeyup="value="/blog/value.replace(/["^u4E00-u9FA5] /g,") " onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^u4E00-u9FA5]/g,"))"
用正则表达式限制只能输入全角字符: onkeyup="value="/blog/value.replace(/["^uFF00-uFFFF]/g,") " onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^uFF00-uFFFF]/g,"))"
用正则表达式限制只能输入数字:onkeyup="value="/blog/value.replace(/["^d]/g,") “onbeforepaste= “clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^d]/g,"))"
用正则表达式限制只能输入数字和英文:onkeyup="value="/blog/value.replace(/[W]/g,"") “onbeforepaste="clipboardData.setData(’text’,clipboardData.getData(’text’).replace(/[^d]/g,"
使用记录
RegExp 拼接
match 中无法直接拼接,所以只能 通过RegExp 对象进行拼接
去掉头尾反斜,中间需要转义的全部多加个
\再次转义
value = value.toString().match(/^\d{0,8}(?:\.\d{0,4})?/);
let regx2=new RegExp(`^\\d{0,${length}}(?:\\.\\d{0,${length2}})?`);
value.toString().match(regx2);
let 变量 = 3
let regx = new RegExp('/^(123)\d{' + (变量) + '}$/') // 试图插入变量
一个正则.test(123444) // 但是实际结果:false
//理想中:/^(123)\d{3}$/
console.log(一个正则) // 实际输出:/\/^(123)d{3}$\//
//============# 正确的写法 #============
let 变量 = 3
// 去掉头尾反斜,中间需要转义的全部多加个`\`再次转义
let 正确正则 = new RegExp('^(123)\\d{' + (变量) + '}$')
正确正则.test(123444) // true
校验是否为数字
isNumber(num) {
return /^[0-9]+.?[0-9]*$/.test(num)
},
使用 下面的方法,无法识别 字符串类型的数字-不推荐使用
function isNumber(num) {
return typeof num === 'number' && !isNaN(num)
}
格式化日期
20210821 -> 2021-08-21
'20210821'.replace(/^(\d{4})(\d{2})(\d{2})$/, '$1-$2-$3')