2021年正则表达式终极指南(如何在JavaScript中使用)
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
正则表达式在所有高级编程语言中都扮演着至关重要的角色,JavaScript 也不例外。让我们详细了解一下它们……
正则表达式(RegEx)是一串字符,用于定义搜索模式。它可以帮助您根据给定的规则“匹配”文本(字符串)的一部分。
// Let's get our hands dirty with an examples:
const regex = /[A-Z]\w+/g; // (We ommited ' ')
// regex holds a regular expression which will match words starting with a capital letter.
const str = `Rahul, Taylor and Susanne are coders who live in India`;
// When we apply the regex to str, it returns all matches in a simple array!
// console.log( str.match(regex) )
//["Rahul", "Taylor", "Susanne", "India"]
您可以使用纯 JavaScript 实现相同的操作,但正则表达式可以为您节省数百行代码,而且几乎可以与任何语言(甚至命令行工具)一起使用。
核心内容和一些基础知识
编写正则表达式时,它总是以斜杠/开头,以斜杠/结尾。你需要在两个斜杠之间编写代码。最简单的例子是,要匹配单词“apple”,可以使用正则表达式/apple/。但是,它不会匹配“APPLE”或“aPpLe”,因为正则表达式区分大小写。
要在正则表达式中禁用大小写敏感性,请使用所谓的“i”标志,例如`/apple/i`,这样它就能匹配 'apple'、'APPLE' 和 'aPpLe'。要同时匹配 'apple' 和 'nut',请使用正则表达式`apple|nut/`。很简单,对吧?
如何在 JavaScript 中使用
让我们来学习JS中处理正则表达式的最基本方法。
-
`str.match(regex)`:返回一个包含所有匹配项的数组。不过,这里有个小陷阱😉。如果你尝试这样做:
"apple apple" .match(/apple/)你可能会期望得到 `['apple', 'apple']`,但事实并非如此。实际上,它只返回 `['apple']`。要获得包含多个匹配项的完整数组,你应该添加`g`标志。 -
`str.test(str)`:`regex` 是一个赋值给正则表达式的变量。`str`是你要用正则表达式测试的字符串。如果找到匹配项,该方法返回 `true`,否则返回 `false`。
// Let's hang with them
let regex = /code|easy/i;
const str = 'this code is EaSy super easy';
regex.test(str) // true; means we have a match😍
str.match(regex) // ["code", index: 5, input..]
// Oops! We forgot adding the g flag
regex = /code|easy/ig;
str.match(regex) // ["code", "EaSy", "easy"]
// ALRIGHT!!
通配符时期概念
我们学习了如何静态匹配单词,比如“hug”(/hug/)。但如果我们想同时匹配“huh”、“hug”和“hum”呢?答案是:通配符!这样就能匹配所有以“hu”/hu./开头的三个字母的单词。
将单个字符与多个选项匹配
很多时候,你需要的是介于两者之间的效果。.你可能不想使用 `\n` 来选中所有字符,而是只想选中a、b、c、d、e这几个字符。这时,嵌套的“技巧”就派上用场了。
// CHARACTER CLASSES allow you to define a group of characters you wish to match. You put the chards in [] "car cat cam cal car".match(/ca[rt]/g);
// returns: ['car', 'cat', 'car']
// match "bag", "big", "bug", but nit "bog" "big bag has a bug bog".match(/b[aiu]g/g);
// ["big", "bag", "bug"]
// MAKE CHARACTER CLASSES SHORTER by using [X-Y] which will match fro letter x to letter y. Example: [a-zA-Z] will match all capital and not capital letters from a to z
"abcdefghijklmnopqr".match(/[d-j]/g);
// ["d", "e", "f", "g", "h", "i", "j"]
//same as:
"abcdefghijklmnopqr".match(/defghij/g);
// ["d", "e", "f", "g", "h", "i", "j"]
// Use it with a number too:
"1234567890".match(/4-9/g);
//["4", "5", "6", "7, "8", "9"]
反转角色类别
a-z将匹配从 a 到 z 的所有字母。要匹配除字母 a 到 z 之外的所有符号,请使用[^a-z]。该^运算符在 中使用时会反转其行为[ ]。
匹配出现多次的字符
// With +
let regex = /a+/g;
"abc".match(regex) //["a"]
"aabc".match(regex) //["aa"]
"aabac".match(regex) //["aa", "a"]
"bbc".match(regex) //null
//without +
regex = /a/g;
"abc".match(regex) //["a"]
"aabc".match(regex) //["aa"]
"aabac".match(regex) //["aa", "a"]
"bbc".match(regex) //null
从字符串的开头到结尾搜索模式
要使用以下方法在字符串的开头精确搜索字符:^
let regex = /^K/;
regex.test("__K_K_") // false - K is not exactly at the beginning!
regex.test("K___K___") // true
//To search for a character at the end of string use $ like so
regex = /K$/;
regex.test("__K__K_") // false - K has to be at the end
regex.test("__K") // true
可选字符
let regex = /colou?r/; // makes 'u' capital
let american = "color";
let british = "colour";
regex.test(american); // true
regex.test(british); // true
regex.test("cologr"); // false
让我们把这个提升到更高层次。
常用速记
- 而不是
[A-Za=z0-9]
使用 ->\w
- 而不是
[^A-Za-z0-9]
使用 ->\W
- 而不是
[0-9]
\d
- 而不是
^ 0-9
使用 ->\D
指定匹配结果的上限和下限
如果要匹配重复 X 次的字符序列,例如,精确匹配 5 个字母“a”呢?这样做a{5}只会匹配“aaaaa”,而不会匹配“aa”或“aaaaaaa”。
让我们来看看...
let str = "ama baalo maaaaamal aaaaaa";
console.log( str.match(/a{5}/g ) );
//prints ["aaaaa". "aaaaa"]
//to match 'm' letter followed by 5 x 'a'
console.log( str.match( /ma{5}/ ) );
// prints ["maaaaa", indes: 10, ...]
//which means we have a match at index 10
// to match empty space followed by 4 x 'a'
console.log( str.match(/\sa{4}/ ) );
// prints [" aaaa", index: 19, ...]
// match at index 19
你已经看到了如何匹配特定数量的重复字符,a{5}例如匹配“aaaaa”。但如果你想匹配的不是正好5个重复字符,而是更灵活一些的重复字符数——1到3个呢?下面我们来看一下,a{1,3}它可以匹配“a”、“aa”、“aaa”,但不会匹配“aaaa”。
我们还可以更进一步——省略第一个或第二个参数a{3}将不会匹配“a”、“aa”,而是匹配“aaa”、“aaaa”或更高。
## 匹配多次出现的字符
以上我们已经简要介绍了这个话题,现在是时候深入探讨了。
- 要匹配一个或多个字符,请在目标字符后使用。
let str = "ama balo maaaaamal";
console.log( str.match( /a+/g ) );
// ["a", "a", "aa", "aaaaa", "a"]
console.log( str.match( /a/g ) );
// ["a", "a", "a", "a", "a", "a", "a", "a", "a", "a"]
- 要匹配零个或多个字符,请在目标字符后加 ue。
let str = "aaa";
console.log( str.match( /a*/g ) );
// ["aaa", ""]
consolle.log( str.match( /a/g ) );
// ["a", "a", "a"]
- 要匹配零个或一个字符,请在目标字符后使用逗号。
let str = "aaa";
console.log( str.match( /a?/g ) );
// ["a", "a", "a", ""]
积极和消极的展望
这被认为是正则表达式中比较抽象的主题之一,但我会尽量涵盖你需要知道的 80% 的内容。
a(?=g)- 正向前瞻匹配所有后面跟着“g”的“a”,但不将“g”作为匹配的一部分。a(?!g)- 否定前瞻匹配所有后面不跟“g”的“a”,而不将“g”作为匹配的一部分。
但它还可以更加灵活。请看这个例子 ->(?=regex) ?!regex
你可以用任何有效的正则表达式替换原有的正则表达式。我们先来看看……
let str = "IsFunBaloonIsLearningRegExIsLean";
console.log (str.match( /Is(?=Learning)/ ) );
//["Is", index: 11, ...]
//Matches the 2nd "Is", right before "Learning"
console.log( str.match( /Is(?=Lean)/ ) );
//["Is", index: 26, ...]
//Match the 3rd "Is", right before "Lean"
console.log( str.match( /Is(?=L)/g ) );
// ["Is", "Is"]
//Matches all "Is" which are followed by "L"
console.log( str.match(/Is(?!L)/ ) );
//["Is", index:0, ...]
// Matches all "Is" which aren't followed by "L"
如果你想反其道而行之——检查目标字符之前的字符,而不是之后的字符呢?你可以使用后向断言(LookBehind) ;P
重用捕获组的模式
我们都知道DRY编程原则——不要重复自己。捕获组正是帮助我们做到这一点的。
/(bam+)\w\1/g same as
/(bamm+)\w(bamm+)/g same as
/bamm+\wbamm+/g
/(\w+)\s(\1\1\1)\2/g same as
/(\w+)\s\1\1\1\1\1\1/g
/(\w+)\s\1\1\1/g same as
/\w+\s\w+\w+\w+/g
现在让我们来学习如何释放正则表达式的强大功能,并将其运用到你的 JavaScript 技能中!
在 JavaScript 中创建正则表达式
let regex = /a[0-9]b+/
//if you want to pass flags (like i and g)
let regex = /a[0-9]b+/ig
-> 脚本加载时编译
- 使用正则表达式构造函数
let regex - new RegExp('a[0-9]b+')
//if you want to pass flags (like i and g)
let regex = new RegExp('a[0-9]b+', 'ig')
-> 运行时编译
旗帜
在 JavaScript 中,我们有 6 个标志会影响匹配结果:
- i - 使匹配不区分大小写。'C' 和 'c' 没有区别。
- g - 如果没有此标志,则只会返回第一个匹配项。
- m
^- 多行更多;仅影响and的行为$ - s - 点模式;允许使用通配符句点
.匹配换行符\n - u - 已启用完整的 Unicode 支持
- y - 粘滞模式。启用后可在特定位置搜索。
让我们来看看以某种形式使用正则表达式的 JS 方法。
str.match(regexp)-在字符串str中查找所有与正则表达式匹配的项,并返回这些匹配项的数组。regexp.exec(str)- 类似于 match 方法,但它用于循环中,此时正则表达式存储在全局变量中,而不是直接传递。
// Difference between the two methods
let re = /bla/g;
let str = "bla and yea bla yeh";
re.exec(str)
// -> ["bla", index: 0, ...]
re.exec(str)
// -> ["bla", index: 13, ...]
re.exec(str)
// -> null
re.exec(str)
// -> ["bla", index: 0, ...]
// STARTS AGAIN
//USAGE WITH A LOOP
let match, str = "bla and yeah bla yeh ble";
while (mathc = re.exec(str)) {
console.log(match);
}
// ["bla", index: 0, input: ...]
// ["bla", index: 13, input: ...]
// on the other side, match works pretty simple
str.match(re)
// ["bla", "bla"]
str.matchAll(regexp)- 新增 JS 特性并改进了 match 方法。3 项改进:- 返回一个包含匹配项的可迭代对象,而不是数组。
str.match每场比赛的格式与没有“g”标志时相同。- 如果没有匹配项,它将返回一个空的可迭代对象,而不是像使用 match 时那样返回 null。
使用此功能时务必添加g标志!
let regexp = /bla/g;
let str = 'bla and yeah bla yeh';
const matches = str.matchAll(regexp);
for (let match of matches) {
console.log(match)
}
// ["bla", index: 0, ...]
// ["bla", index: 13, ...]
-
regexp.test(str)- 在字符串中查找至少一条与正则表达式匹配的项。如果找到,则返回 true;否则返回 false。 -
str.search(regexp)- 返回第一个可用匹配项的索引。如果未找到匹配项,则返回 -1。 -
str.match(separator)除了传递像单引号这样的简单字符串作为分隔符之外,我们还可以传递正则表达式来进行更精确的分割。 -
str.replace(from, to)` from`参数指定要匹配的内容。它可以是字符串或正则表达式。第一个匹配项将被替换为您传递给 ` to`参数的字符串。除了字符串之外,您还可以传递一个函数,但这超出了本教程的范围。 -
str.repalceAll(from,to)与替换操作相同,区别在于它不是只替换第一个匹配项,而是将所有匹配项替换为指定的值。例如:
let str = "stuffed str living fforever pff"
let regex = /f+/; //match one or more 'f'
let repl = str.replace(regex, '*');
//repl is "stu*ed str living fforeverpff"
let repl = str.replaceAll(regex, '*');
// repl is "stu*ed str living *orever p*"
// NOTE: If you add g flag to replace it works like replaceAll
有点难也比较长。希望你喜欢!欢迎在评论区分享你的看法和问题。
🔐感谢阅读 | 祝您编程愉快📘
文章来源:https://dev.to/devbookmark/super-ultimate-guide-to-regex-in-2021-how-to-use-in-javascript-ki