什么是正则表达式
正则表达式,常常缩写为 “regex” 或 “regexp”,是帮助程序员匹配、搜索和替换文本的模式。
1. 正则表达式的测试方法
regex.test('string') 返回 boolean 类型的值,即 true 或 false
const testStr = 'hello world'
const regex = /hello/
const result = regex.test(testStr)
console.log(result) // true
复制代码
'string'.match(regex)
用于提取具体的匹配项
返回所有匹配项的字符串数组
// 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/i
const result = regex.test(testStr) // true
const result2 = regex.test(testStr) // true
复制代码
4. 全局匹配, 使用标志 g
g
此 flag 用于多次搜寻或者提取模式匹配
// 从twinkleStar 中提取所有的twinkle
let twinkleStar = "Twinkle, twinkle, little star";
let starRegex = /twinkle/gi;
let result = twinkleStar.match(starRegex); // ['Twinkle', 'twinkle']
复制代码
5. 通配符 . 匹配任何内容
题目: 完成正则表达式 unRegex
以匹配字符串 run
、sun
、fun
、pun
、nun
和 bun
。 正则表达式中应该使用通配符
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]/gi
let 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 line
let 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]/g
let result = movieName.match(noNumRegex).length;
复制代码
21. 练习题
用户名只能是数字字母字符。
用户名中的数字必须在最后。 数字可以有零个或多个。 用户名不能以数字开头。
用户名字母可以是小写字母和大写字母。
用户名长度必须至少为两个字符。 两位用户名只能使用字母
let username = "JackOfAllTrades";
let userCheck = /^[a-z][a-z]+\d*$|^[a-z]\d\d+$/gi
let 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
以匹配出现 3
到 6
次字母 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,也可以不匹配u
rainbowRegex.test(american); // true
rainbowRegex.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 Roosevelt
或 Eleanor 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);
复制代码
待续...
评论