断言
断言包括边界,它们指示行和单词的开始和结束,以及以某种方式指示可能匹配的其他模式(包括先行断言、后行断言和条件表达式)。
试一试
const text = "A quick fox";
const regexpLastWord = /\w+$/;
console.log(text.match(regexpLastWord));
// Expected output: Array ["fox"]
const regexpWords = /\b\w+\b/g;
console.log(text.match(regexpWords));
// Expected output: Array ["A", "quick", "fox"]
const regexpFoxQuality = /\w+(?= fox)/;
console.log(text.match(regexpFoxQuality));
// Expected output: Array ["quick"]
类型
边界型断言
| 字符 | 含义 |
|---|---|
^ |
输入边界起始断言: 匹配输入的开头。如果启用了 注意: 当此字符出现在字符类的开头时,它具有不同的含义。 |
$ |
输入边界结束断言: 匹配输入的结尾。如果启用了 |
\b |
单词边界断言: 匹配一个单词边界。这是单词字符不紧接或不前接另一个单词字符的位置,例如字母和空格之间。请注意,匹配的单词边界不包含在匹配结果中。换句话说,匹配的单词边界的长度为零。 示例
要匹配退格字符( |
\B |
非单词边界断言: 匹配非单词边界。这是前一个字符和后一个字符类型相同的位置:它们必须都是单词字符,或者都必须是非单词字符,例如两个字母之间或两个空格之间。字符串的开头和结尾被视为非单词。与匹配的单词边界一样,匹配的非单词边界也不包含在匹配结果中。例如, |
其他断言
注意: ? 字符也可以用作量词。
| 字符 | 含义 |
|---|---|
x(?=y) |
先行断言: 只有当“x”后面跟着“y”时才匹配“x”。例如, |
x(?!y) |
否定先行断言: 只有当“x”后面没有跟着“y”时才匹配“x”。例如, |
(?<=y)x |
后行断言: 只有当“x”前面跟着“y”时才匹配“x”。例如, |
(?<!y)x |
否定后行断言: 只有当“x”前面没有跟着“y”时才匹配“x”。例如, |
示例
通用边界型概述示例
// Using Regex boundaries to fix buggy string.
buggyMultiline = `tey, ihe light-greon apple
tangs on ihe greon traa`;
// 1) Use ^ to fix the matching at the beginning of the string, and right after newline.
buggyMultiline = buggyMultiline.replace(/^t/gim, "h");
console.log(1, buggyMultiline); // fix 'tey' => 'hey' and 'tangs' => 'hangs' but do not touch 'traa'.
// 2) Use $ to fix matching at the end of the text.
buggyMultiline = buggyMultiline.replace(/aa$/gim, "ee.");
console.log(2, buggyMultiline); // fix 'traa' => 'tree.'.
// 3) Use \b to match characters right on border between a word and a space.
buggyMultiline = buggyMultiline.replace(/\bi/gim, "t");
console.log(3, buggyMultiline); // fix 'ihe' => 'the' but do not touch 'light'.
// 4) Use \B to match characters inside borders of an entity.
fixedMultiline = buggyMultiline.replace(/\Bo/gim, "e");
console.log(4, fixedMultiline); // fix 'greon' => 'green' but do not touch 'on'.
使用 ^ 控制字符匹配输入的开头
使用 ^ 匹配输入的开头。在此示例中,我们可以通过正则表达式 /^A/ 获取以“A”开头的单词。为了选择合适的水果,我们可以使用 filter 方法和箭头函数。
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Select fruits started with 'A' by /^A/ Regex.
// Here '^' control symbol used only in one role: Matching beginning of an input.
const fruitsStartsWithA = fruits.filter((fruit) => /^A/.test(fruit));
console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
在第二个示例中,^ 既用于匹配输入的开头,也用于在字符类中使用时创建否定或补足的字符类。
const fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
// Selecting fruits that do not start by 'A' with a /^[^A]/ regex.
// In this example, two meanings of '^' control symbol are represented:
// 1) Matching beginning of the input
// 2) A negated or complemented character class: [^A]
// That is, it matches anything that is not enclosed in the square brackets.
const fruitsStartsWithNotA = fruits.filter((fruit) => /^[^A]/.test(fruit));
console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
请参阅输入边界断言参考中的更多示例。
匹配单词边界
在此示例中,我们匹配包含以“en”或“ed”结尾的单词的水果名称。
const fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
// Select descriptions that contains 'en' or 'ed' words endings:
const enEdSelection = fruitsWithDescription.filter((description) =>
/(?:en|ed)\b/.test(description),
);
console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
请参阅单词边界断言参考中的更多示例。
先行断言
在此示例中,我们只匹配单词“First”,前提是它后面跟着单词“test”,但我们不将“test”包含在匹配结果中。
const regex = /First(?= test)/g;
console.log("First test".match(regex)); // [ 'First' ]
console.log("First peach".match(regex)); // null
console.log("This is a First test in a year.".match(regex)); // [ 'First' ]
console.log("This is a First peach in a month.".match(regex)); // null
请参阅先行断言参考中的更多示例。
基本否定先行断言
例如,/\d+(?!\.)/ 只有当数字后面没有小数点时才匹配数字。/\d+(?!\.)/.exec('3.141') 匹配“141”但不匹配“3”。
console.log(/\d+(?!\.)/g.exec("3.141")); // [ '141', index: 2, input: '3.141' ]
请参阅先行断言参考中的更多示例。
“?!”组合在断言和字符类中的不同含义
?! 组合在断言(如 /x(?!y)/)和字符类(如 [^?!])中具有不同的含义。
const orangeNotLemon =
"Do you want to have an orange? Yes, I do not want to have a lemon!";
// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and Ranges /[^?!]/
const selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
const selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi;
console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
后行断言
在此示例中,我们只在单词“orange”前面跟着单词“ripe”时才将其替换为“apple”。
const oranges = ["ripe orange A", "green orange B", "ripe orange C"];
const newFruits = oranges.map((fruit) =>
fruit.replace(/(?<=ripe )orange/, "apple"),
);
console.log(newFruits); // ['ripe apple A', 'green orange B', 'ripe apple C']
请参阅后行断言参考中的更多示例。