深入理解正则表达式的预查(Lookahead and Lookbehind)
在正则表达式中,预查(Lookahead and Lookbehind)是一种强大的工具,允许你在不消耗字符的情况下进行匹配检查。预查可以分为四种类型:正向肯定预查、正向否定预查、反向肯定预查和反向否定预查。
1. 正向肯定预查(Positive Lookahead)
概念
正向肯定预查用于确保某个模式出现在当前位置之后,但不会消耗该模式中的字符。语法为 (?=...)
,其中 ...
是你要查找的模式。
应用场景
当你需要匹配某个模式,且该模式后面必须紧跟另一个特定模式时,可以使用正向肯定预查。
示例
假设我们有一个字符串 "apple pie, banana cake, cherry pie"
,我们想找到所有以 "pie"
结尾的单词。
const str = "apple pie, banana cake, cherry pie";
const regex = /\b\w+(?= pie)/g;
const matches = str.match(regex);
console.log(matches); // 输出: ["apple", "cherry"]
解释
\b
:单词边界。\w+
:匹配一个或多个字母数字字符。(?= pie)
:正向肯定预查,确保当前单词后面紧跟" pie"
。
2. 正向否定预查(Negative Lookahead)
概念
正向否定预查用于确保某个模式不在当前位置之后出现,也不会消耗该模式中的字符。语法为 (?!...)
,其中 ...
是你不希望出现的模式。
应用场景
当你需要匹配某个模式,且该模式后面不能紧跟另一个特定模式时,可以使用正向否定预查。
示例
假设我们有一个字符串 "apple 123, cake 456, banana 789"
,我们想找到所有不以数字[1-6]为结尾的单词。
const str = "apple 123, cake 456, banana 789";
const regex = /\b[a-z]+\b(?! [1-6]+)/g;
const matches = str.match(regex);
console.log(matches); // 输出: ["banana"]
解释
\b[a-z]+\b
:匹配完整的单词。(?! [1-6]+)
:正向否定预查,确保单词后面不能紧跟数字[1-6]。
3. 反向肯定预查(Positive Lookbehind)
概念
反向肯定预查用于确保某个模式出现在当前位置之前,但不会消耗该模式中的字符。语法为 (?<=...)
,其中 ...
是你要查找的模式。
应用场景
当你需要匹配某个模式,且该模式前面必须紧跟着另一个特定模式时,可以使用反向肯定预查。
示例
假设我们想找出所有前面跟着 “$” 的数字
const text = "The price is $100 and $200.";
const regex = /(?<=\$)\d+/g;
const matches = text.match(regex);
console.log(matches); // 输出: [ '100', '200' ]
解释
(?<=\$)
:反向肯定预查,确保数字前面跟着一个$
;\d+
: 匹配一个或多个数字。
4. 反向否定预查(Negative Lookbehind)
概念
反向否定预查用于确保某个模式不在当前位置之前出现,也不会消耗该模式中的字符。语法为 (?<!...)
,其中 ...
是你不希望出现的模式。
应用场景
当你需要匹配某个模式,且该模式前面不能紧跟着另一个特定模式时,可以使用反向否定预查。
示例
假设我们想找出所有不前面跟着 “$” 的数字。
const text = "The price is $100 and 200.";
const regex = /(?<!\$)\b\d+/g;
const matches = text.match(regex);
console.log(matches); // 输出: [ '200' ]
解释
(?<!\$)
:反向否定预查,确保前面没有紧跟"$"
。\b\d+
: 匹配一个单词边界,然后匹配一个或多个数字。
5.总结
- 正向肯定预查 (
(?=...)
):确保当前位置后面紧跟指定模式。 - 正向否定预查 (
(?!...)
):确保当前位置后面不紧跟指定模式。 - 反向肯定预查 (
(?<=...)
):确保当前位置前面紧跟着指定模式。 - 反向否定预查 (
(?<!...)
):确保当前位置前面不紧跟着指定模式。