来说说正则表达式中的前瞻和后瞻,及经典应用示例。
在正则表达式中,前瞻(lookahead)和后瞻(lookbehind)是两种高级特性,它们用于匹配在某个位置前后特定的条件,而不包括这些条件本身在结果中。
顾名思义,前瞻就是往前看一下,后瞻就是往后看一下(废话文学)
正则表达式(Regular Expressions,简称regex)是一种用于字符串匹配和操作的强大工具。在正则表达式中,前瞻(lookahead)和后瞻(lookbehind)是两种高级特性,它们用于匹配在某个位置前后特定的条件,而不包括这些条件本身在结果中。
前瞻(Lookahead)
前瞻用于检查在当前位置之后是否存在某个模式,但不消耗字符。前瞻分为肯定前瞻和否定前瞻。
肯定前瞻又叫正向前瞻(Positive Lookahead)
语法:(?=pattern)
肯定前瞻在当前位置之后匹配pattern
,但不包括pattern
本身在结果中。例如:
- 正则表达式:
\d(?=abc)
- 目标字符串:
1abc2abc3abc
- 结果:匹配到的结果是
1
,2
,3
肯定前瞻示例
let text = "1abc2abc3abc";
let pattern = /\d(?=abc)/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '1', '2', '3' ]
解释:\d
匹配一个数字,(?=abc)
确保数字后面紧跟abc
,但不包括abc
在结果中。
否定前瞻又叫负向前瞻(Negative Lookahead)
语法:(?!pattern)
否定前瞻在当前位置之后不应匹配pattern
。例如:
- 正则表达式:
\d(?!abc)
- 目标字符串:
1xyz2abc3def
- 结果:匹配到的结果是
1
,3
否定前瞻示例
let text = "1xyz2abc3def";
let pattern = /\d(?!abc)/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '1', '3' ]
解释:\d
匹配一个数字,(?!abc)
确保数字后面不紧跟abc
。
后瞻(Lookbehind)
后瞻用于检查在当前位置之前是否存在某个模式,但不消耗字符。后瞻分为肯定后瞻和否定后瞻。
肯定后瞻又叫正向后瞻(Positive Lookbehind)
语法:(?<=pattern)
肯定后瞻在当前位置之前匹配pattern
,但不包括pattern
本身在结果中。例如:
- 正则表达式:
(?<=abc)\d
- 目标字符串:
abc1def2abc3
- 结果:匹配到的结果是
1
,3
肯定后瞻示例
let text = "abc1def2abc3";
let pattern = /(?<=abc)\d/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '1', '3' ]
解释:\d
匹配一个数字,(?<=abc)
确保数字前面紧跟abc
,但不包括abc
在结果中。
否定后瞻又叫负向后瞻(Negative Lookbehind)
语法:(?<!pattern)
否定后瞻在当前位置之前不应匹配pattern
。例如:
- 正则表达式:
(?<!abc)\d
- 目标字符串:
xyz1abc2def3
- 结果:匹配到的结果是
1
,3
否定后瞻示例
let text = "xyz1abc2def3";
let pattern = /(?<!abc)\d/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '1', '3' ]
解释:\d
匹配一个数字,(?<!abc)
确保数字前面不紧跟abc
。
综合示例
假设有一个字符串列表,我们希望匹配所有以美元符号开头的数字,但这些数字后面必须紧跟一个非数字字符:
let text = "The prices are $30, $50, and $70each.";
let pattern = /\$\d+(?=\D)/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '$30', '$50' ]
解释:\$
匹配美元符号,\d+
匹配一个或多个数字,(?=\D)
确保这些数字后面紧跟一个非数字字符,但不包括这个非数字字符在结果中。
经典应用
好的,这里提供一些经典的示例,展示如何在JavaScript中使用正则表达式的前瞻和后瞻来解决实际问题。
1. 匹配以特定后缀结尾的单词
假设你需要匹配所有以"ing"结尾的单词,但不包括"ing"在结果中:
let text = "I am running and jumping, not walking or singing.";
let pattern = /\b\w+(?=ing\b)/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ 'runn', 'jump', 'walk', 'sing' ]
解释:\b\w+
匹配一个单词,(?=ing\b)
确保单词后面是"ing",但不包括"ing"在结果中。
2. 提取所有以特定前缀开头的单词
假设你需要提取所有以"pre"开头的单词,但不包括"pre"在结果中:
let text = "This is a prerequisite and a preview of the presentation.";
let pattern = /(?<=\bpre)\w+\b/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ 'requisite', 'view', 'sentation' ]
解释:(?<=\bpre)
确保单词前面是"pre",\w+\b
匹配单词的其余部分。
3. 查找不在引号中的单词
假设你需要查找不在引号(单引号或双引号)中的单词:
let text = `He said "Hello" and then he said 'Goodbye'.`;
let pattern = /\b\w+\b(?![^'"]*['"])/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ 'He', 'said', 'and', 'then', 'he', 'said' ]
解释:\b\w+\b
匹配一个单词,(?![^'"]*['"])
确保单词后面不跟随任意数量的非引号字符然后是引号。
4. 提取所有数字并忽略负数
假设你需要提取所有数字,但忽略负数:
let text = "The temperatures are -5, 10, 15, and -20 degrees.";
let pattern = /(?<!-)\b\d+\b/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ '10', '15' ]
解释:(?<!-)
确保数字前面没有负号,\b\d+\b
匹配数字。
5. 提取邮件地址的用户名部分
假设你需要提取邮件地址的用户名部分("@"之前的部分):
let text = "Contact us at support@example.com or sales@company.com.";
let pattern = /\b[A-Za-z0-9._%+-]+(?=@)/g;
let matches = text.match(pattern);
console.log(matches); // 输出: [ 'support', 'sales' ]
解释:[A-Za-z0-9._%+-]+
匹配邮件地址的用户名部分,(?=@)
确保其后跟随"@",但不包括"@"在结果中。
这些示例展示了如何使用前瞻和后瞻来解决实际问题,帮助你更灵活地处理字符串匹配任务。希望这些示例对你有帮助!如果你有其他特定需求或问题,请随时告诉我。
总结
前瞻和后瞻在正则表达式中提供了灵活的匹配能力,可以用于复杂的模式匹配需求。理解它们的语法和应用场景,将有助于更高效地处理字符串匹配问题。