写点什么

正则表达式知识点梳理

作者:真嗣
  • 2022 年 5 月 18 日
  • 本文字数:4572 字

    阅读完需:约 15 分钟

正则表达式知识点梳理

什么是正则表达式

正则表达式,常常缩写为 “regex” 或 “regexp”,是帮助程序员匹配、搜索和替换文本的模式。

1. 正则表达式的测试方法

  1. regex.test('string') 返回 boolean 类型的值,即 true 或 false

const testStr = 'hello world'const regex = /hello/const result = regex.test(testStr)console.log(result) // true
复制代码
  1. 'string'.match(regex)

  2. 用于提取具体的匹配项

  3. 返回所有匹配项的字符串数组

// 1. 用于提取具体的匹配项const testStr = 'hello world'const regex = /hello/const result = testStr.match(regex) // ['hello', index: 0, input: 'hello world', groups: undefined]
// 2. 返回所有匹配项的字符串数组// 注意 ourRegex 增加了 g flag 用于多次提取匹配项let testStr2 = "Repeat, Repeat, Repeat";let ourRegex = /Repeat/g;let ourRegex2 = /Repeat/testStr2.match(ourRegex) // ['Repeat', index: 0, input: 'Repeat, Repeat, Repeat', groups: undefined]testStr2.match(ourRegex) // ['Repeat', 'Repeat', 'Repeat']
复制代码

2. | 操作符

此操作符匹配操作符前面或者操作符后面的字符。具体写法即/regex1|regex2/

const testStr = 'James has a pet cat, you have a pet dog, i have a pet bird'const regex = /cat|dog/const result = regex.test(testStr) // true// 匹配是否包含字符cat 或者字符 dog
复制代码

3. 忽略大小写,通过标志(flag)i 进行匹配

i 此 flag 可以忽略匹配的字符串的大小写,具体写法:/regexPattern/i

const testStr = 'FreECodeCamp'const testStr2 = 'FREECODECAMP'const regex = /freecodecamp/iconst result = regex.test(testStr) // trueconst result2 = regex.test(testStr) // true
复制代码

4. 全局匹配, 使用标志 g

g 此 flag 用于多次搜寻或者提取模式匹配

// 从twinkleStar 中提取所有的twinklelet twinkleStar = "Twinkle, twinkle, little star";let starRegex = /twinkle/gi; let result = twinkleStar.match(starRegex);  // ['Twinkle', 'twinkle']
复制代码

5. 通配符 . 匹配任何内容

题目: 完成正则表达式 unRegex 以匹配字符串 runsunfunpunnunbun。 正则表达式中应该使用通配符

let exampleStr = "Let's have fun with regular expressions!";let unRegex = /.un/; // 修改这一行let result = unRegex.test(exampleStr);console.log(result) // true// unRegex 可以匹配任何 un 相关的字符串
复制代码

6. 单个字符与多种可能性的匹配

通过把字符放入[ 和 ] 之间来定义一组需要匹配的字符串

let quoteSample = "Beware of bugs in the above code; I have only proved it correct, not tried it.";let vowelRegex = /[aeiou]/gi;let result = quoteSample.match(vowelRegex);// result 的值将是所有 a e i o u 字符串的集合
复制代码

7. 匹配字母表中的字母

可以使用 - 连字符 来定义要匹配的字符范围

例如,要匹配小写字母 a 到 z, 你可以使用[a-z]

let quoteSample = "The quick brown fox jumps over the lazy dog.";let alphabetRegex = /[a-z]/gi; // 修改这一行let result = quoteSample.match(alphabetRegex); // 修改这一行console.log(result)
// 或者let catStr = "cat";let batStr = "bat";let matStr = "mat";let bgRegex = /[a-e]at/;catStr.match(bgRegex);batStr.match(bgRegex);matStr.match(bgRegex);
复制代码

8. 匹配字母表中的数字和字母

let jennyStr = "Jenny8675309";let myRegex = /[a-z0-9]/ig;let result = jennyStr.match(myRegex)
复制代码

9. 匹配单个未指定的字符

使用 ^ 字符来创建一个不想匹配的字符集, 即否定字符集,例如,可以使用/[^aeiou]/gi来匹配所有非元音的字符。

// 创建一个匹配所有非数字或元音字符的正则表达式。 请记得在正则表达式中包含恰当的标志// myRegex 或者 myRegex2的写法都可以let quoteSample = "3 blind mice.";let myRegex = /[^aeiou^0-9]/gilet myRegex2 = /[^aeiou|^0-9]/let result = quoteSample.match(myRegex)console.log(result)
复制代码

10. 匹配出现 1 次或者多次的字符

使用 + 符号来检查是否匹配

let difficultSpelling = "Mississippi";let myRegex = /s+/g;let result = difficultSpelling.match(myRegex);console.log(result) // ['ss', 'ss']
复制代码

11. 匹配 0 次或者多次的字符

使用 * 符号来检查是否匹配

let soccerWord = "gooooooooal!";let gPhrase = "gut feeling";let oPhrase = "over the moon";let goRegex = /go*/;soccerWord.match(goRegex); // ['goooooooo', index: 0, input: 'gooooooooal!', groups: undefined]gPhrase.match(goRegex); // ['g', index: 0, input: 'gut feeling', groups: undefined]oPhrase.match(goRegex); // null

let chewieQuote = "Aaaaaaaaaaaaaaaarrrgh!";let chewieRegex = /Aa*/; // Change this linelet result = chewieQuote.match(chewieRegex);
复制代码

13. 惰性匹配来查找字符

在正则表达式中,贪婪(greedy)匹配会匹配到符合正则表达式匹配模式的字符串的最长可能部分,并将其作为匹配项返回。另一种方案称为懒惰(lazy)匹配,它会匹配到满足正则表达式的字符串的最小可能部分

懒惰匹配 使用 ? 匹配符进行懒惰匹配ß

let reg = /t[a-z]*?i/'titanic'.match(reg) // ['ti', index: 0, input: 'titanic', groups: undefined]
// 修复正则表达式 /<.*>/,让它返回 HTML 标签 <h1>,而不是文本 "<h1>Winter is coming</h1>"。 请记得在正则表达式中使用通配符 . 来匹配任意字符。let text = "<h1>Winter is coming</h1>";let myRegex = /<.*?>/;let result = text.match(myRegex);ßconsole.log(result)
复制代码

14. 匹配字符串的开头

以 ^ 来匹配字符串的开头,注意与第 9 条的区别

let rickyAndCal = "Cal and Ricky both like racing.";let calRegex = /^Cal/; let result = calRegex.test(rickyAndCal); // true
复制代码

15. 匹配字符串的末尾

以 $ 来搜寻字符串的结尾

let caboose = "The last car on a train is the caboose";let lastRegex = /caboose$/;let result = lastRegex.test(caboose); // true
复制代码

16. 匹配所有的字母和数字

可以使用元字符 \w 来进行匹配,与 \w 最接近的是 [a-zA-Z0-9_] 。类似 \w 这种元字符的索耶也被称为短语元字符

let quoteSample = "The five boxing wizards jump quickly.";let alphabetRegexV2 = /\w/g;let result = quoteSample.match(alphabetRegexV2).length;
复制代码

18. 匹配除了数字和字母以外的所有字符

可以使用 \W 短语元字符, 注意此处的 W 是大写,刚好与 \w 相反。

let quoteSample = "The five boxing wizards jump quickly.";let nonAlphabetRegex = /\W/g;let result = quoteSample.match(nonAlphabetRegex).length;
复制代码

19. 匹配所有数字

可以使用 \d 短语元字符。其中 \d 等同于 [0-9]

let movieName = "2001: A Space Odyssey";let numRegex = /\d/g;// let numRegex = /[0-9]/g // 也是可以的let result = movieName.match(numRegex).length; // 4
复制代码

20. 匹配所有非数字

可以使用 \D 短语元字符,注意 D 为大写,\D 等同于 [^0-9]

let movieName = "2001: A Space Odyssey";let noNumRegex = /\D/g;// let noNumRegex = /[^0-9]/glet result = movieName.match(noNumRegex).length;
复制代码

21. 练习题

  1. 用户名只能是数字字母字符。

  2. 用户名中的数字必须在最后。 数字可以有零个或多个。 用户名不能以数字开头。

  3. 用户名字母可以是小写字母和大写字母。

  4. 用户名长度必须至少为两个字符。 两位用户名只能使用字母

let username = "JackOfAllTrades";let userCheck = /^[a-z][a-z]+\d*$|^[a-z]\d\d+$/gilet result = userCheck.test(username);
复制代码

22. 匹配空白字符串

可以使用 \s 搜寻空格,其中 s 是小写。 此匹配模式将匹配空格、回车符、制表符、换页符和换行符。 可以认为这类似于元字符 [ \r\t\f\n\v]

// 找出sample多个空白字符let sample = "Whitespace is important in separating words";let countWhiteSpace = /\s/g;let result = sample.match(countWhiteSpace);
复制代码

23. 匹配非空白字符

使用 \S 搜寻非空白字符,其中 s 是大写。 此匹配模式将不匹配空格、回车符、制表符、换页符和换行符。 可以认为这类似于元字符 [^ \r\t\f\n\v]

let sample = "Whitespace is important in separating words";let countNonWhiteSpace = /\S/g; // 修改这一行let result = sample.match(countNonWhiteSpace)
复制代码

24. 指定匹配的上限和下限

可以使用数量说明符,指定匹配模式的上下限。数量说明符与花括号( { 和 } ) 一起使用。可以在花括号之间放两个数字,这两个数字代表匹配模式的上限和下限。

如果匹配 h 字符 3 到 6 次就可以写为 h{3, 6},其中,3 代表匹配模式的下限即最少几个,6 代表匹配模式的上限即最多几个

题目:

修改正则表达式 ohRegex 以匹配出现 36 次字母 h 的字符串 Oh no

let ohStr = "Ohhh no";let ohRegex = /Oh{3,6}\s*no/;let result = ohRegex.test(ohStr);
复制代码

25. 只指定匹配的下限

使用数量说明符, 可以写为{3,} 即可。不需要指定上限即可匹配 3+个字符

题目:匹配包含四个或更多字母 z 的单词 Hazzah

let haStr = "Hazzzzah";let haRegex = /Haz{4,}ah/;let result = haRegex.test(haStr);
复制代码

26. 指定匹配的确切数量

使用数量说明符,花括号中写具体的数量即可。例如,要只匹配字母 a 出现 3 次的单词hah,正则表达式应为/ha{3}h/

题目:修改正则表达式timRegex,以匹配仅有四个字母 m 的单词 Timber

let timStr = "Timmmmber";let timRegex = /Tim{4}ber/; let result = timRegex.test(timStr);
复制代码

27. 检查全部或者无

当想要搜寻的匹配模式可能有不确定是否存在的部分,但是还想要进行匹配,那么可以选择使用问号 ? 指定可能存在的元素。 ? 可以检查前面的零个或者一个元素。理解为 ? 前面的一个元素是可选的。

例如,美式英语和英式英语略有不同,可以使用问号来匹配两种拼写

let american = "color";let british = "colour";let rainbowRegex= /colou?r/; // 可以匹配u,也可以不匹配urainbowRegex.test(american); // truerainbowRegex.test(british) // true
let favWord = "favorite";let favRegex = /favou?rite/;let result = favRegex.test(favWord);
复制代码

28. 正向先行断言和负向先行断言

正则表达式的先行断言(lookahead)和后行断言(lookbehind) | 菜鸟教程

题目:在正则表达式 pwRegex 中使用先行断言以匹配大于 5 个字符且有两个连续数字的密码

// 答案一let sampleWord = "astronaut";let pwRegex =  /(?=\w{6})(?=\w*\d{2})/;let result = pwRegex.test(sampleWord);
// 答案二let sampleWord = "astronaut";let pwRegex = /(?=\w{6,})(?=\w*\d\d+)/;let result = pwRegex.test(sampleWord);
复制代码

29. 检查混合字符串组

题目:完善正则表达式,使其以区分大小写的方式检查 Franklin RooseveltEleanor Roosevelt 的名字,并且应该忽略 middle names。

// 答案一let myString = "Eleanor Roosevelt";let myRegex = /(Franklin|Eleanor).*Roosevelt/;let result = myRegex.test(myString);// 答案二let myString = "Eleanor Roosevelt";let myRegex = /(Eleanor|Franklin)\s*.*\s* Roosevelt/; let result = myRegex.test(myString); 
复制代码

待续...

发布于: 刚刚阅读数: 4
用户头像

真嗣

关注

fly me to the moon 2020.07.07 加入

还未添加个人简介

评论

发布
暂无评论
正则表达式知识点梳理_正则表达式_真嗣_InfoQ写作社区