var re = /http\:\/{2}/;
re.test('http://jobs.douban.com') //true
//用构造函数创建正则往往要对特殊字符双重转义var re = new RegExp('http\\:\\/{2}');
re.test('http://jobs.douban.com') //true
//ES6允许用第二个参数覆盖默认的标志修饰符,ES5则会报错
var re2 = new RegExp(/abc/ig, 'i');
console.log(re2.flags); //i
方法 | 所属 | 描述 |
---|---|---|
exec | RegExp | 在字符串中查找匹配,返回一个特殊数组(未匹配到则返回null) |
test | RegExp | 在字符串中测试是否匹配,返回true或false |
match | String | 在字符串中查找匹配,返回一个特殊数组或者在未匹配到时返回null |
search | String | 在字符串中测试匹配,返回匹配到的位置索引,或者在失败时返回-1 |
replace | String | 在字符串中查找匹配,并且使用替换字符串替换掉匹配到的子字符串 |
split | String | 使用正则或字符串分隔一个字符串,并将分隔后的子字符串存储为数组 |
将其后的特殊字符,转义为字面量
标志 | 描述 |
---|---|
g | 全局搜索 |
i | 不区分大小写搜索 |
m | 多行搜索 |
y | ES6新增,执行“粘性”搜索,匹配从目标字符串的当前位置开始 |
u | ES6新增,含义为“Unicode模式”,会正确处理四个字节的UTF-16编码(大于\uFFFF) |
global //是否设置了g
ignoreCase //是否设置了i
multiline //是否设置了m
lastIndex //0开始的整数,开始搜索下一个匹配项的位置
source //正则字面量的字符串表示
sticky //ES6新增,表示是否设置了y修饰符
flags //ES6新增,会返回正则表达式的修饰符
var exec = /abc\s\"h\d/.exec('helloabc "h2elloabc"'); // ["abc "h2"]
exec.index // 5
exec.input // 'helloabc "h2elloabc"'
//在global情况下
var re = /\del/g, txt = '1ello, 2elabc';
console.log(re.exec(txt)); // ["1el"], index: 0, input: "1ello, 2elabc"
console.log(re.exec(txt)); // ["2el"], index: 7, input: "1ello, 2elabc"
//特殊字符`?`, 编码U+10437
/?{2}/u.test('??') //true
/?{2}/.test('??') //false
//y和g的区别在于不是紧跟着的粘连模式,相当于隐含的^头部匹配
var str = "applewatch";
var re = /a/g;
re.exec(str); //['a'] index:0
re.exec(str); //['a'] index:6
re.exec(str); //null
var re2 = /a/y;
re2.exec(str); //['a'] index:0
re2.exec(str); //null
var re = /(\de(l.))/g, txt = '1ello, 2elabc';
re.exec(txt);
console.log(RegExp.$1, RegExp.$2);//'1ell', 'll'
re.exec(txt);
console.log(RegExp.$1, RegExp.$2);//'2ela', 'la'
var str = "吃葡萄不吐putao皮,不吃putao倒吐葡萄皮~";
var str2 = str.replace(/葡萄|putao/g, pt=>{
console.log(pt);
return '苹果';
});
//葡萄
//putao
//putao
//葡萄
//str2 == "吃苹果不吐苹果皮,不吃苹果倒吐苹果皮~"
//中文、英文、数字及下划线
^[\u4e00-\u9fa5_a-zA-Z0-9]+$//中国邮政编码
[1-9]{1}(\d+){5}//email地址
/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;//根据useragent判断是否ios
/iP(od|ad|hone)\;?.*\sOS\s([\_0-9]+)///去掉首位空格
str.replace(/(^\s+|\s+$)/g, '')//格式化手机号
tel.replace(/(.{4})/g, '$1 ') //"1332 3385 333"/**
* 获取基于模板的文本值
* @param {String} tmpl - 文本模板,格式为 'hello{0},world{1}'
* @param {...String} args - 用于替换的若干参数
* @return {String}
*/
function read_i18n(tmpl, ...args) {
let rtn = tmpl.substr(0);
if (args.length) {
let flagArr = tmpl.match(/\{\d+\}/g); //{1},{0},{2}...
if (flagArr) {
for (let i = 0; i < flagArr.length; i++) {
rtn = rtn.replace(
new RegExp("\\{" + i + "\\}", "g"),
args[i]
);
}
}
}
return rtn;
}read_i18n('hello{0}world{1}', '!', ':)'); // 'hello!world:)'
var txt = '<a href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度</a>'
var re1 = /\<a (.*?)\<\/a\>/g; //懒惰模式,尽可能少的匹配
var re2 = /\<a (.*)\<\/a\>/g; //贪婪模式,尽可能多的匹配, 区别在不加问号console.log(re1.exec(txt));
//["<a href=”http://google.com”>谷歌</a>", "href=”http://google.com”>谷歌"]console.log(re1.exec(txt));
//["<a href=”http://baidu.com”>百度</a>", "href=”http://baidu.com”>百度"]console.log(re2.exec(txt));
//["<a href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度</a>",
//"href=”http://google.com”>谷歌</a><a href=”http://baidu.com”>百度"]console.log(re2.exec(txt));
//null
(?:x)
模式的括号被成为非捕获分组,从而不让这个分组被类似 macth exec 这样的函数所获取到
var reg = /test(?:\d)+/; var str = 'new test001 test002'; console.log(str.match(reg)); //["test001", index: 4, input: "new test001 test002"]
蒹葭苍苍,白露为霜。所谓伊人,在水一方。溯洄从之,道阻且长。溯游从之,宛在水中央
/h(ello|appy) hippo/.test("hello there, happy hippo");
var re1 = /<p>.*<\/p>/i;
var re2 = /<p>.*?<\/p>/i; //非贪婪(懒惰)
var str1 = "<p>Para.1.</p><img src='smiley.jpg'><p>Para.2.</p><div>Div.</div>";
var str2 = "<p>Para.1.</p>";
/<html>[\s\S]*?<head>[\s\S]*?<\/head>[\s\S]*?<body>[\s\S]*?<\/body>[\s\S]*?<\/html>/
</html>
,则最后一个[\s\S]*?
扩展到字符串末尾且无法匹配成功[\s\S]*?
,并将其扩展到字符串末尾,尝试 "....</body>...</body>...</html>"
的情况[\s\S]*?
扩展到字符串末尾并失败,从而引发失控/<html>(?:(?!<head>)[\s\S])*<head>(?:(?!<title>)[\s\S])*<title>(?:(?!<\/title>)[\s\S])*<\/title>(?:(?!<\/head>)[\s\S])*<\/head>(?:(?!<body>)[\s\S])*<body>(?:(?!<\/body>)[\s\S])*<\/body>(?:(?!<\/html>)[\s\S])*<\/html>/
[\s\S]*?
/<html>(?=([\s\S]*?<head>))\1(?=([\s\S]*?<title>))\2(?=([\s\S]*?<\/title>))\3(?=([\s\S]*?<\/head>))\4(?=([\s\S]*?<body>))\5(?=([\s\S]*?<\/body>))\6[\s\S]*?<\/html>/
\x
语法在“捕获和非捕获分组”中介绍过(?=(pattern))\x
模拟;其特点是其中的分组中的任何回溯点都将被丢弃</html>
,则最后一个[\s\S]*?
扩展到字符串末尾,且整个表达式立即失败,因为没有位置可以回溯了/(A+A+)+B/.test('AAAAAAAAAA')
/AA+B/
/((?=(A+A+))\2)+B/
调试正则时需要考虑的两个因素是准确性和效率:精确匹配需要的文本,并且速度要快
^
等,避免用分支开头[a-z\r\n]*
的就不用.*
[cb]at
代替cat|bat
,或用[\s\S]
代替(.|\r|\n)
;常用字符放在集合的前面