捕获
圆括号用来实现捕获功能。被捕获的匹配可以被回溯引用。
一个简单的捕获匹配例子是这样的: (x)
匹配 x
并且可以通过 $1
引用到捕获的值。
当然,也有对应的“非捕获匹配”:(?:x)
就表示“匹配 x
但是不记住它”。这样就不能通过 $1
来引用它了。
正向肯定查找
x(?=y)
匹配 x 当且仅当 x 的后面紧跟着 y 。
示例:遮挡手机号中间4位
有时出于保护用户隐私的考虑,会把11位手机号的中间部分进行遮挡,例如号码 13678954321,希望显示为 136**4321 ,即保留前3位和后4位,遮挡中间的4位数字。
'13678954321'.replace(/\d{4}(?=\d{4}\b)/, '****'); // "136****4321"
示例:遮挡中文姓名的第二个字
有时候,产品经理希望遮挡用户的真实姓名的第二个字(因为是中文环境,用户的真实姓名都是不少于两个汉字的)。这时候可能需要考虑的有这几个点:
- 中文字符没有字符边界的概念
\w
无法匹配中文字符
不过,解决方案也是有的。中文字符也好,英文字符也好,都不能是空字符。在信任数据库里用户姓名的可靠性后,可以认为不存在那些奇奇怪怪的字符。那么可以这样:
'东'.replace(/(\S)\S?/, '$1*'); // '东*'
'东邪'.replace(/(\S)\S?/, '$1*'); // '东*'
'东邪西毒'.replace(/(\S)\S?/, '$1*'); // '东*西毒'
这个对英文也是一样的效果。
正向否定查找
x(?!y)
匹配 x 当且仅当 x 的后面没有 y 。
综合示例:数字格式化
把按照每3位加一个逗号的格式进行格式化。例如 1000
,格式化后为 1,000
。
'$49000000.00'.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'); // "$49,000,000.00"
这段正则表达式的意思是,从第一个数字开始,它的后面需要紧跟着一个连续的3的倍数个数字串,这个串的后面没有任何数字。
这段的执行速度是非常快的,连续执行1000次,Chrome 下耗时 4ms:
var start = +new Date();
for(var i=0; i<1000; i++){
'$49540000.00'.replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
}
var end = +new Date();
console.log(end-start); // 4