JavaScript的正则(RegExp)
前言
此文不作正则规则讲解,只写JavaScript对正则的应用。
一、RegExp 的应用
活着的意义是处理字符:
解析,提取一段字符中想要的内容。如:
- 解析括号内的内容
"he(llow)orld".match(/\((.+?)\)/)[1];//llow
- 解析括号内的内容
格式检查 ,常用于校验字符串是否满足条件,如
- 校验输入内容必须为正数
/^[1-9]\d*$/.test("123");//true
- 校验输入内容不能带有*号:
/^((?!\*).)*$/.test("dsd*dsad");//false
检索替换 ,替换符合正则的内容,如
- 替换文字中所有A:
"ABABABA".replace(/A/g,"a");//aBaBaBa
正则语法:详见:https://blog.csdn.net/xiaolongbaobushibao/article/details/81980161
二、 RegExp对象
2.1、 *RegExp.prototype.exec()
方法在一个指定字符串中执行一个搜索匹配。返回一个结果数组或 null
。
var reg = /(\w+)@(\w+)\.(\w+)/g;
var result = reg.exec("[email protected]");
console.log(result);
/*
[
0:"[email protected]",
1:"pony",
2:"11",
3:"com",
index:0,
input:"[email protected]"
]
*/
2.2、*RegExp.prototype.test()
方法执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 true
或 false
。 常用于表单校验。
/[0-9]/.test("1111");//true
/[0-9]/.test("abcd");//false
2.3、RegExp.prototype[@@match]()
match 方法会返回一个数组,它包括整个匹配结果,和通过捕获组匹配到的结果,如果没有匹配到则返回nul.
IE 不支持!
/a/[Symbol.match]('abc');
以上的方法在 String.prototype.match()被调用,String可以直接使用match
'abc'.match(/a/);
2.4、RegExp.prototype.toString()
toString 方法返回一个该正则表达式的字符串形式。
2.5、RegExp.prototype.source
与RegExp.prototype.toString()
类似,区别在于toString是个方法,source是个不可变属性,且source
不含双斜杠以及flags
(gi…)
var regex = new RegExp("foo", "m")
console.log(regex.source) // foo
console.log(/foo/m.source);//foo
/[0-9]/g.toString();// /[0-9]/g
2.6、RegExp.prototype.toSource()
RegExp.prototype.toSource()
Chrome 67.0.3396.87
不支持,该特性是非标准的,请尽量不要在生产环境中使用它!
2.7、RegExp.prototype.compile()
RegExp.prototype.compile()
已废弃,请勿使用
2.8、*RegExp.prototype.flags
只读Boolean类型属性。代表是否使用g
,表示所有可能的匹配。
var regex = new RegExp("foo", "gimuy")
console.log(regex.flags ) // gimuy
console.log(/foo/g.flags )//g
- flags
简写 | 完整名字 | 含义 |
---|---|---|
g | global | 表示全局匹配,能匹配多少是多少 |
i | ignore | 忽略大小写 |
m | multiline | 多行匹配。 |
u | unicode | 任何 Unicode 代码点的转义都会被解释 |
y | sticky | 自定义锚点,从锚点开始匹配 |
2.9、RegExp.prototype.global
只读Boolean类型属性。代表是否使用g
,表示所有可能的匹配。
var regex = new RegExp("foo", "g")
console.log(regex.global) // true
console.log(/foo/g.global)
2.10、RegExp.prototype.ignoreCase
只读Boolean类型属性。代表是否使用i
,表示匹配忽略大小写。
var regex = new RegExp("foo", "i")
console.log(regex.ignoreCase) // true
console.log(/foo/i.ignoreCase)
2.11、RegExp.prototype.multiline
multiline
是一个布尔对象,如果使用了 “m
” 标志,则返回 true
;否则,返回 false
。”m
” 标志意味着一个多行输入字符串被看作多行。例如,使用 “m
“,”^
” 和 “$
” 将会从只匹配正则字符串的开头或结尾,变为匹配字符串中任一行的开头或结尾。
var regex = new RegExp("foo", "m")
console.log(regex.multiline) // true
console.log(/foo/m.multiline)
例子:
"BBB\nAAA".replace(/^([A])/,"【$1】");//只能匹配字符串最开头
//BBB
//AAA
"BBB\nAAA".replace(/^([A])/m,"【$1】");//换行操作也可以当做开头,所以符合要求
//"BBB
//【A】AA"
2.12、RegExp.prototype.unicode
u
标志开启了多种 Unicode 相关的特性。使用 “u” 标志,任何 Unicode 代码点的转义都会被解释
var regex = new RegExp('\u{61}', 'u');
console.log(regex.unicode); // true
2.13、RegExp.prototype.sticky
锚点,表示从下标n开始匹配。
var regex = new RegExp("h", "y");
regex.test("_hello");//false:默认lastIndex = 0,所以从第一个字符开始匹配
regex.lastIndex = 1;//
regex.test("_hello");// true:锚点设置在第二个字符,以第二个字符为开始匹配
三、 RegExp 方法
以下特性是非标准的,请尽量不要在生产环境中使用它! (虽然非标准,但是所有浏览器都支持…)
3.1、*RegExp.$n
成功匹配后会生成:RegExp.$1
- RegExp.$9
的只读属性,存储最新的一次匹配值。
例子:
var reg = /(\w+)@(\w+)\.(\w+)/g;
var result = reg.exec("[email protected]");
console.log("邮箱名:"+RegExp.$1,"二级域名:"+RegExp.$2,"顶级级域名:"+RegExp.$3,"其他匹配:"+RegExp.$4);
//邮箱名:pony 二级域名:qq 顶级级域名:com 其他匹配:
```
每个括号匹配一个内容,第一个括号内容赋值给了`$1`,以此类推,如果如果存储的内容少于9个,那么没有赋值的为`""`,最多只能存储到`$9`。
```javascript
console.log(JSON.stringify(result))
//["[email protected]","pony","qq","com"]
<div class="se-preview-section-delimiter"></div>
还是上面的例子,result生成的是一个数组。所以可以根据下标去取值。$1 == result[1]
3.2、RegExp["{0}"]
var reg = /(ABCD)/g;
var str = "abcdABCDEFGABCDHIJK"
var result=reg.exec(str);
console.log(RegExp["$&]);//ABCD
<div class="se-preview-section-delimiter"></div>
"ABCDEFGABAB".replace(/A/g,"【$&】");//"【A】BCDEFG【A】B【A】B"
<div class="se-preview-section-delimiter"></div>
3.3、RegExp.index
、RegExp.lastIndex
(仅IE支持)
index:第一次匹配的位置,lastIndex最后一次匹配的位置。
var reg = /(ABCD)/g;
var str = "abcdABCDEFGABCDHIJK"
var result=reg.exec(str);
console.log(RegExp.$1,RegExp.index,RegExp.lastIndex);
// IE:ABCD 4 8
// CHROME ABCD undefined undefined
<div class="se-preview-section-delimiter"></div>
chrome 只能通过返回值拿到第一次匹配的位置result.index
3.4、RegExp.lastMatch
最后一次匹配内容
var reg = /(ABCD)/g;
var str = "abcdABCDEFGABCDHIJK"
var result=reg.exec(str);
console.log(RegExp.lastMatch);//ABCD
<div class="se-preview-section-delimiter"></div>
input
被匹配的原字符串
var reg = /(ABCD)/g; var str = "abcdABCDEFGABCDHIJK" var result=reg.exec(str); console.log(RegExp.input,RegExp.input == result.input);//abcdABCDEFGABCDHIJK true
四、 RegExp 实例化
4.1、快速使用实例化对象
var reg1 = /[0-1]+/
<div class="se-preview-section-delimiter"></div>
4.2、字符串参数构造函数
原型
new RegExp(pattern [, flags])
例子
var reg2 = new RegExp("[0-1]","g");
注意
构造函数实例化的时候,
pattern
字符参数不能带有特殊字符
,不然会有以下问题:var regStr = "*";//这里用赋值代替输入 var reg = new RegExp(regStr,"g");//生成正则对象 /* ERROR Uncaught SyntaxError: Invalid regular expression: /* /: Nothing to repeat at new RegExp (<anonymous>) at <anonymous>:1:11 */
解决方案:
- (1)转义特殊字符
var str = "AB*CD"; var regStr = "\\*";//这里用赋值代替输入,两个\\代表最终字符串为 \* var reg = new RegExp(regStr,"g");//生成正则对象 str.replace(reg,"");//正常输出 "ABCD"
通用一点就是:
var getRegExp = function (substr,modifiers) { if(typeof str !== 'string'){ return new RegExp(str); } const regExpStr = str.replace(/\$|\(|\)|\*|\+|\.|\[|\]|\?||\^|\{|\}||/g,function(){ return "\\"+arguments[0]; }) return new RegExp(regExpStr,modifiers); }
- (2)使用
unicode
// String to unicode var encodeUnicode = function (str) { var res = []; for ( var i=0; i<str.length; i++ ) { res[i] = ( "00" + str.charCodeAt(i).toString(16) ).slice(-4); } return "\\u" + res.join("\\u"); } var getRegExp = function (substr,modifiers) { if(typeof str !== 'string'){ return new RegExp(str); } return new RegExp(encodeUnicode(substr),"u"+(modifiers||"")); }
- (1)转义特殊字符
五、
String
相关的正则的方法
5.1 String.prototype.match
当一个字符串与一个正则表达式匹配时, match()方法检索匹配项。
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matches_array = str.match(regexp);
<div class="se-preview-section-delimiter"></div>
内部直接调用/a/[Symbol.match]('abc');
,所以等价于
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matches_array = regexp[Symbol.match](str);
<div class="se-preview-section-delimiter"></div>
5.2 String.prototype.search
字符串中是否存在某个模式(pattern)时可使用 search
,类似于正则表达式的 test
方法。当要了解更多匹配信息时,可使用 match
(会更慢),该方法类似于正则表达式的 exec
方法。
var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[D]/;
str.search(regexp);// 3
//JSON.stringify(regexp.exec(str)) == JSON.stringify(str.match(regexp)); //["D"]
regexp.exec(str);//[0:"D",index:3,input:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"]
str.match(regexp);//[0:"D",index:3,input:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"]
<div class="se-preview-section-delimiter"></div>
5.3 String.prototype.split
str.split([separator[, limit]])
<div class="se-preview-section-delimiter"></div>
- separator 可以是一个字符串或正则表达式
- limit 一个整数,限定返回的分割片段数量。
例子:
//字符串分割
"Webkit Moz O ms Khtml".split( " " ) // ["Webkit", "Moz", "O", "ms", "Khtml"];
//正则分割
var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ;Chris Hand ";
var re = /\s*;\s*/;
var nameList = names.split(re);//["Harry Trump","Fred Barney","Helen Rigby","Bill Abel","Chris Hand "]
<div class="se-preview-section-delimiter"></div>
注意:在某些低版本的IE(IE8?)无法使用正则分割字符串
5.4 RegExp.prototype.test
校验最常用的就是这个了
/[0-9]/.test("1111");//true
/[0-9]/.test("abcd");//false