正则表达式学习总结(二)
位置
正则表达式的位置是指相邻字符之间的位置,也就是锚
6个锚:^、$、\b、\B、(?=p)、(?!p)
- ^(脱字符)匹配开头,在多行匹配中匹配行开头
- $(美元符号)匹配结尾,在多行匹配中匹配行结尾
- \b 是单词边界,具体就是 \w 与 \W 之间的位置,也包括 \w 与 ^ 之间的位置,和 \w 与 $ 之间的位置
- \B 就是 \b 的反面的意思,非单词边界。例如在字符串中所有位置中,扣掉 \b,剩下的都是 \B 的
- (?=p),其中 p 是一个子模式,即 p 前面的位置,或者说,该位置后面的字符要匹配 p,学名positive lookahead,即先行断言
- (?!p) 就是 (?=p) 的反面意思,要求接下来的字符与 p 匹配,但不能包括 p 匹配的那些字符,学名negative lookahead即后行断言
测试:
- 不匹配任何东西的正则
var regec = /.^/
1
- 数字的千位分隔符表示法: "12345678",变成 "12,345,678"
var regec = /\B(?=(\d{3})+\b)/g
1
- 验证密码问题:同时包含数字和小写字母,同时包含数字和大写字母,同时包含小写字母和大写字母, 同时包含数字、小写字母和大写字母
var regex = /((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[A- Z]))^[0-9A-Za-z]{6,12}$/
1
- 验证密码问题: 不能全部都是数字,也不能全部都是小写字母,也不能全部都是大写字母
var regex = /(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;
1
括号
括号两大作用:分组和分支结构
分支:多选分支结构 (p1|p2) 中,提供了分支表达式的所有可能
分组引用:可以用于数据提取以及替换操作,分组后面有量词的话,分组最终捕获到的数据是最后一次的匹配
示例:
数据提取
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
console.log( string.match(regex) );
// => ["2017-06-12", "2017", "06", "12", index: 0, input: "2017-06-12"]
1
2
3
4
2
3
4
match 返回的一个数组,第一个元素是整体匹配结果,然后是各个分组(括号里)匹配的内容,然后是匹配下标,最后是输入的文本。另外,正则表达式是否有修饰符 g,match返回的数组格式是不一样的 数据替换
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result);
// => "06/12/2017"
1
2
3
4
5
2
3
4
5
replace 中的,第二个参数里用 $1、$2、$3 指代相应的分组
反向引用
反向引用,是引用前面的分组,正则里引用了不存在的分组时,此时正则不会报错,只是匹配 反向引用的字符本身。
var regex = /\d{4}(-|\/|\.)\d{2}\1\d{2}/;
var string1 = "2017-06-12";
var string2 = "2017/06/12";
var string3 = "2017.06.12";
var string4 = "2016-06/12";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // true
console.log( regex.test(string4) ); // false
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
里面的 \1,表示的引用之前的那个分组 (-|/|.)。不管它匹配到什么(比如 -),\1 都匹配那个同 样的具体某个字符,注意如果要匹配 \1 和 0 的话,请使用 (?:\1)0 或者 \1(?:0)
非捕获括号
只想要括号最原始的功能,但不会引用它,即,既不在 API 里引用,也不在正则里反向引用,此时可以使用非捕获括号 (?:p) 和 (?:p1|p2|p3)
var regex = /(?:ab)+/g;
var string = "ababa abbb ababab";
console.log( string.match(regex) );
// => ["abab", "ab", "ababab"]
var regex = /^I love (?:JavaScript|Regular Expression)$/;
console.log( regex.test("I love JavaScript") );
console.log( regex.test("I love Regular Expression") );
1
2
3
4
5
6
7
2
3
4
5
6
7
示例:
- 字符串 trim 方法模拟
// 第一种,匹配到开头和结尾的空白符,然后替换成空字符
var reges = /^\s+|\s+$/g
// 第二种,匹配整个字符串,然后用引用来提取出相应的数据
str.replace(/^\s*(.*?)\s*$/g, "$1")
1
2
3
4
2
3
4
- 将每个单词的首字母转换为大写
function titleize (str) {
return str.toLowerCase().replace(/(?:^|\s)\w/g, function (c) {
return c.toUpperCase();
});
}
console.log( titleize('my name is epeli') );
1
2
3
4
5
6
2
3
4
5
6
- 驼峰化
function camelize (str) {
return str.replace(/[-_\s]+(.)?/g, function (match, c) {
return c ? c.toUpperCase() : '';
});
}
console.log( camelize('-moz-transform') );
1
2
3
4
5
6
2
3
4
5
6
- 中划线化
function dasherize (str) {
return str.replace(/([A-Z])/g, '-$1').replace(/[-_\s]+/g, '-').toLowerCase();
}
console.log( dasherize('MozTransform') );
1
2
3
4
2
3
4
- HTML 转义和反转义
// 将HTML特殊字符转换成等值的实体 function escapeHTML (str) {
var escapeChars = {
'<' : 'lt',
'>' : 'gt',
'"' : 'quot',
'&' : 'amp',
'\'' : '#39'
};
return str.replace(new RegExp('[' + Object.keys(escapeChars).join('') +']', 'g'),
function (match) {
return '&' + escapeChars[match] + ';';
});
}
console.log( escapeHTML('<div>Blah blah blah</div>') );
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
- 匹配成对标签
var regex = /<([^>]+)>[\d\D]*<\/\1>/;
var string1 = "<title>regular expression</title>";
var string2 = "<p>laoyao bye bye</p>";
var string3 = "<title>wrong!</p>";
console.log( regex.test(string1) ); // true
console.log( regex.test(string2) ); // true
console.log( regex.test(string3) ); // false
1
2
3
4
5
6
7
2
3
4
5
6
7