正则匹配模式
在了解正则匹配模式前,先了解一个概念即正则回溯
- 回溯是指正则表达式引擎在匹配过程中遇到无法匹配的情况时,会回退到之前的某个状态,尝试其他可能的匹配路径,直到找到匹配为止
正则表达式匹配模式有 贪婪模式、懒惰模式(非贪婪)、独占模式,贪婪模式是默认匹配模式
- 贪婪模式 - 量词会尽可能多的匹配字符,即最多匹配原则,但会进行回溯
- 懒惰模式 - 量词会尽可能少的匹配字符,即最少匹配原则
- 独占模式 - 量词会尽可能多的匹配字符,一旦匹配便不会回溯
- 正则量词 - ? * + {n,m} 等
在JS中是不支持 独占模式 的,常见语言中Java等支持
匹配模式
贪婪模式匹配
// ? 重复0-1次,按最多匹配原则
console.log( /abc?/.test('abcxyz') + ' -> ' + /abc?/.exec('abcxyz') ); // true -> abc
// * 重复0-n次,按最多匹配原则
console.log( /123*/.test('1233xyz') + ' -> ' + /123*/.exec('1233xyz') ); // true -> 1233
// + 重复1-n次,按最多匹配原则
console.log( /123+/.test('1233xyz') + ' -> ' + /123+/.exec('1233xyz') ); // true -> 1233
// {1,} 重复1-n次,按最多匹配原则
console.log( /123{1,}/.test('1233xyz') + ' -> ' + /123{1,}/.exec('1233xyz') ); // true -> 1233
// {1,2} 重复1-2次,按最多匹配原则
console.log( /123{1,2}/.test('1233xyz') + ' -> ' + /123{1,2}/.exec('1233xyz') ); // true -> 1233
贪婪模式回溯
// ? 重复0-1次,按最多匹配原则,但后面还要匹配c,只有回溯才能匹配上
console.log( /abc?c/.test('abcxyz') + ' -> ' + /abc?c/.exec('abcxyz') ); // true -> abc
// * 重复0-n次,按最多匹配原则,但后面还要匹配33,只有回溯才能匹配上
console.log( /123*33/.test('1233xyz') + ' -> ' + /123*33/.exec('1233xyz') ); // true -> 1233
// + 重复1-n次,按最多匹配原则,但后面还要匹配3,只有回溯才能匹配上
console.log( /123+3/.test('1233xyz') + ' -> ' + /123+3/.exec('1233xyz') ); // true -> 1233
// {1,} 重复1-n次,按最多匹配原则,但后面还要匹配3,只有回溯才能匹配上
console.log( /123{1,}3/.test('1233xyz') + ' -> ' + /123{1,}3/.exec('1233xyz') ); // true -> 1233
// {1,2} 重复1-2次,按最多匹配原则,但后面还要匹配3,只有回溯才能匹配上
console.log( /123{1,2}3/.test('1233xyz') + ' -> ' + /123{1,2}3/.exec('1233xyz') ); // true -> 1233
懒惰模式匹配
// ? 重复0-1次,按最少匹配原则
console.log( /abc??/.test('abcxyz') + ' -> ' + /abc??/.exec('abcxyz') ); // true -> ab
// * 重复0-n次,按最少匹配原则
console.log( /123*?/.test('1233xyz') + ' -> ' + /123*?/.exec('1233xyz') ); // true -> 12
// + 重复1-n次,按最少匹配原则
console.log( /123+?/.test('1233xyz') + ' -> ' + /123+?/.exec('1233xyz') ); // true -> 123
// {1,} 重复1-n次,按最少匹配原则
console.log( /123{1,}?/.test('1233xyz') + ' -> ' + /123{1,}?/.exec('1233xyz') ); // true -> 123
// {1,2} 重复1-2次,按最少匹配原则
console.log( /123{1,2}?/.test('1233xyz') + ' -> ' + /123{1,2}?/.exec('1233xyz') ); // true -> 123
匹配模式实例
// 当我们匹配一个html标签时,可以如下匹配,获取的是完整的 a 标签,此处体现了量词默认匹配的贪婪行为
console.log( /<.+>/.test('<a class="ok">hello</a>') ) // true
console.log( /<.+>/.exec('<a class="ok">hello</a>') ); // <a class="ok">hello</a>
// 当我们匹配一个html标签时,如果我们只想获取开始标签,可以如下匹配,此处使用了量词匹配的懒惰模式
console.log( /<.+?>/.test('<a class="ok">hello</a>') ) // true
console.log( /<.+?>/.exec('<a class="ok">hello</a>') ); // <a class="ok">