"(pattern)" 将 pattern 部分组合成一个可统一操作的组合项和子匹配,每个捕获的子匹配项按照出现的顺序存储在缓冲区中。缓冲区编号从 1 开始,最多可存储 99
个子匹配捕获的内容。存储在缓冲区中的子匹配捕获的内容,可以在编程语言中被检索,也可以在正则表达式中被反向引用。若要匹配字面意义的括号字符 (
和 )
,在正则表达式中要分别使用 (
和 )
。
在子模式中,其返回的包含其子分组的详细信息。
var s = 'ab=21,bc=45,cd=43';
var r = /(\w+)=(\d*)/;
var a = s.match(r); // 返回数组 "ab=21,ab,21"
"\num" 匹配编号为 num 的缓冲区所保存的内容, num 是标识特定缓冲区的一位或两位十进制正整数,这种方式称为子匹配的反向引用。反向引用能提供表示相同匹配项的能力。
引用的是前一个子表达式的文本,而不是前一个表达式的模式。像下面就会报错:
var s = '<h1>title</h1><p>text</p>';
var r = /(<(\/?)\w+>).\*\1/g;
var a = s.match(r); //
null;
但是想完美匹配,就只能这样:
var s = '<h1>title</h1><p>text</p>';
var r = /(<(\/?)\w+>).\*((<\/?\w+>))/g;
var a = s.match(r);
// <h1>title</h1><p>text</p>
反向引用的值可以从 RegExp() 构造函数中获得。
var s = 'abcdefghijklmn';
var r = /(\w)(\w)(\w)/;
var a = r.test(s);
alert(RegExp.$1); // a
alert(RegExp.$2); // b
alert(RegExp.$3); // c
alert(RegExp.$4); //
正则表达式分组会占用一定的系统资源,在较长的正则表达式中,储存反向引用会降低匹配速度。但是,很多时候使用分组是为了设置操作单元,这时候就需要一种非引用型分组,它不会创建反向引用。
"(?:pattern)" 匹配 pattern 但不获取匹配结果,也就是说,这是一个非捕获匹配,不进行存储供以后使用。它是将 pattern 部分组合成一个可统一操作的组合项,但不把这部分内容当作子匹配捕获,即 pattern 部分是一个非捕获匹配,匹配的内容不存储在缓冲区中供以后使用。这对必须进行组合但又不想让组合的部分具有子匹配特点的情况很有用。
例如,要将 abc?
中的 abc
组合起来,但并不想将匹配的内容保存在缓冲区中,应该使用 (?:abc)?
,而不能使用 (abc)?
。又如,不能将 industry|industries
简单改写为
industry(ylies)
,若不需要引用或检索括号中的表达式所匹配的结果,最好还是写成 industry(?:ylies)
。
声明量词分正向和反向两种:
正向声明:声明表示条件的意思,是指定匹配模式后面的字符必须被匹配,但不返回匹配结果正向声明使用 "(?=( 条件 ))" 表示。
var s = 'a:123 b=345';
var r = /\w*(?==)/; //使用正向声明
var a = s.match(r); // b
"(?=pattern)" 称为正向 " 预测先行 " 匹配,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。在被搜索字符串的相应位置必须有 pattern 部分匹配的内容,但不作为匹配结果处理,更不会存储在捕获缓冲区中供以后使用。
例如, "Windows(?=NT|2000)" 只与 "Windows 2000" 或 "Windows NT" 中的 "Windows" 匹配,而不与 "Windows 2003" 中的 "Windows" 匹配。
注意 该模式下匹配的结果只是 "Windows" 部分,而使用 "Windows(?:NT|2000)" 匹配的是整个 "Windows 2000" 或 "Windows NT" 。如果要将 "NT" 和 "2000" 前面的 "Windows" 替换成 "Win" ,需要使用 "Windows(?=NT|2000)" ,而不能使用 "Windows(?:NT|2000)" ,否则,整个 "Windows 2000" 或 "Windows NT" 将被替换成 "Win" 。
"(?!pattern)" 称为反向 " 预测先行 " 匹配,在被搜索字符串的相应位置不能有 pattern 部分匹配的内容。此外,其功能与正向 " 预测先行 " 匹配一样。
例如, "Windows(?!NT|2000)" 不与 "Windows 2000" 或 "Windows NT" 中的 "Windows" 匹配,而可以与 "Windows 2003" 中的 "Windows" 匹配。
声明虽然包含在小括号内,但不是分组。目前, JavaScript 仅支持正向匹配,不支持反向匹配
var result = '12345678'.replace(/(?=\d{3}$)/g, ',');
console.log(result); // => "12345,678"
var result = '12345678'.replace(/(?=(\d{3})+$)/g, ',');
console.log(result); // => "12,345,678"
var result = '123456789'.replace(/(?=(\d{3})+$)/g, ',');
console.log(result); // => ",123,456,789"
var regex = /(?!^)(?=(\d{3})+$)/g;
var result = '12345678'.replace(regex, ',');
console.log(result); // => "12,345,678"
result = '123456789'.replace(regex, ',');
console.log(result); // => "123,456,789"
var string = '12345678 123456789',
regex = /(?!\b)(?=(\d{3})+\b)/g;
var result = string.replace(regex, ',');
console.log(result); // => "12,345,678 123,456,789"
function format(num) {
return num
.toFixed(2)
.replace(/\B(?=(\d{3})+\b)/g, ',')
.replace(/^/, '$$ ');
}
console.log(format(1888)); // => "$ 1,888.00"
var regex =
/((?=.*[0-9])(?=.*[a-z])|(?=.*[0-9])(?=.*[A-Z])|(?=.*[a-z])(?=.*[AZ]))^[0-9A-Za-z]{6,12}$/;
var regex =
/(?!^[0-9]{6,12}$)(?!^[a-z]{6,12}$)(?!^[A-Z]{6,12}$)^[0-9A-Za-z]{6,12}$/;