深入理解正则表达式的预查

1 阅读3分钟

深入理解正则表达式的预查(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.总结

  • 正向肯定预查 ((?=...)):确保当前位置后面紧跟指定模式。
  • 正向否定预查 ((?!...)):确保当前位置后面不紧跟指定模式。
  • 反向肯定预查 ((?<=...)):确保当前位置前面紧跟着指定模式。
  • 反向否定预查 ((?<!...)):确保当前位置前面不紧跟着指定模式。