掌握正则表达式成为算法向导(基础版)
在本文中,我想仔细探讨一下我在学习编程时遇到的最奇怪的论点之一:正则表达式。
每当我使用正则表达式时,我都感觉自己就像站在耶哥蕊特面前的琼恩·雪诺,听她说“你什么都不知道,琼恩·雪诺”。
可能是因为每次接触正则表达式,我都觉得自己对它一无所知☹。似乎总有一些新东西需要学习,而我却错过了或不知道。
我想,任何一位超级程序员第一次接触正则表达式时,都会和我有同样的感受。
在FreeCodeCamp或Codewars上练习了大量算法之后,我可以告诉你,正则表达式一开始确实很难理解,但在解决 JavaScript 中的各种问题时却非常有用且友好。
所以,让我们开始探索正则表达式的世界吧!
正则表达式到底是什么?
根据Mozilla 开发者网络的说法,正则表达式是:
用于匹配字符串中的字符组合的模式。
简而言之,正则表达式允许我们检查字符串中一系列字符的匹配情况。
它们通常用于验证数据、执行高级搜索、替换或更新文本等等。
当你需要在代码中验证电话号码、电子邮件地址或密码等内容时,你需要使用正则表达式。
所以……快来学习它吧!😄
创建正则表达式
在 Javascript 中,有几种方法可以创建正则表达式:
a.正则表达式文字:
这是最常用的语法,也是我将在本文中使用的语法。
语法:let regex = /wizard/;
b.正则表达式构造函数:
当需要动态创建正则表达式时,此语法非常方便。
语法:let regex = new RegExp('wizard');
现在我们知道了如何创建正则表达式,让我们运用这些知识来创建一个简单的正则表达式:
第一个正则表达式:/wizard/;
这是我们想要检查正则表达式的字符串:“成为算法向导非常困难!”。
结果:“成为算法向导非常困难!”。
我们创建的正则表达式与单词 'wizard' 完全匹配。不多不少。
正则表达式 JS 方法
在 JavaScript 中,有多种方法可以使用正则表达式。我仅介绍其中几种。a
. test()函数用于测试正则表达式是否与给定字符串匹配。它返回一个布尔值。
例如:
let string = 'May the Force be with you';
let regex = /Force/;
let result = regex.test(string);
console.log(result); // true
b. match()返回一个包含所有匹配字符组的数组。它始终会针对字符串进行匹配。如果没有找到匹配项,则返回null。
例如:
let string = 'May the Force be with you';
let regex = /Force/;
let result = string.match(regex);
console.log(result);
/**
* output:
* [ 'Force',
index: 8,
input: 'May the Force be with you',
groups: undefined
]
*/
简单图案
到目前为止,我们只使用了这种正则表达式。它匹配的是文字模式。
我们再举一个例子:
let string = 'I find your lack of faith disturbing.';
let regex = /faith/;
let result = string.match(regex);
console.log(result);
/**
* [ 'faith',
index: 20,
input: 'I find your lack of faith disturbing.',
groups: undefined
]
*/
旗帜的乐趣
正则表达式区分大小写,并且只查找第一个匹配项。
正则表达式的发明者 Stephen Cole Kleene 先生是一位非常优秀的人,他为我们提供了不区分大小写和多个匹配项的检查功能。
他允许我们使用所谓的标志。它们使用起来也很简单:只需在结束正斜杠后添加即可。请记住,您可以组合使用不同的标志,并且顺序不会影响搜索。
语法:/pattern/flags
A. g - 全局标志,在第一个匹配项后不返回结果。
示例:
//No Global Flag Example
let string = 'force force force';
let regex = /force/; // no global flag
let result = string.match(regex); //it will return only the first match at index 0
console.log(result);
/**
* [ 'force',
index: 0,
input: 'force force force',
groups: undefined
]
*/
//Example with Global Flag
let string = 'force force force';
let regex = /force/g; // global flag on
let result = string.match(regex); // it will all matches
console.log(result); //['force', 'force', 'force'];
B. i - 不区分大小写标志
示例:
//No Case Insensitive Flag
let string = 'force force Force'; //last word is uppercased
let regex = /force/g; // no case-insensitive flag
let result = string.match(regex); //it will return only the first two matches
console.log(result); //['force', 'force'];
//Case Sensitive Flag
let string = 'force force Force'; //last word is uppercased
let regex = /force/gi; // case-insensitive flag
let result = string.match(regex); //it will return all matches
console.log(result); //['force', 'force', 'Force'];
字符集
它匹配方括号/[abc]/内的任意单个字符。
例如,上面的/[abc]/表示“嘿,在字符串中查找a、b或c
”。 语法:/[abc]/
它匹配字符串中的 a、b 或 c。
示例:
let string = 'foo poo zoo';
let regex = /[fpz]oo/gi; // matches any f, p or z followed by 'oo'
let result = string.match(regex);
console.log(result); //[ 'foo', 'poo', 'zoo' ]
//Using another Character Set it is possible to match any Vowels like 'o' 😉
//Take a look:
let string = 'foo poo zoo';
let regex = /[fpz][aeiou][aeiou]/gi; // matches any f, p or z followed by a couple of vowels
let result = string.match(regex);
console.log(result); //[ 'foo', 'poo', 'zoo' ]
//Another one:
let string = 'foo faa fee';
let regex = /f[aeiou][aeiou]/gi; // matches any f followed by a couple of vowels
let result = string.match(regex);
console.log(result); //[ 'foo', 'faa', 'fee' ]
否定字符集
如果插入符号跟在左括号后面,它会匹配任何未包含在括号中的内容/[^abc]/
。
例如,上面的/[^abc]/
意思是“查找字符串中除a、b或c之外的字符” 。
示例:
let string = 'fun sun gun';
let regex = /[^fs][aeiou]n/gi; // matches anything but f and s followed by a vowel and a 'n'
let result = string.match(regex);
console.log(result); //[ 'gun' ]
//Look at this one
let string = 'fun sun gun';
let regex = /[fsg][^aeiou]n/gi; // matches f,s or g followed by a letter except a vowel and then by a n
let result = string.match(regex);
console.log(result); //null
范围
方括号也可以包含要在字符串中查找的字符范围,例如/[ac]/。
例如,上面的/[ac]/表示“嘿,在字符串中查找从a到c的字符范围” 。它将搜索 a、b 和 c。
使用以下正则表达式查找字母表中的任意字母非常容易:/[az]/
语法:/[a-c]/
它匹配字符串中的 a、b 或 c。
示例:
let string = 'fear tear bear';
let regex = /[a-z]ear/gi; // matches any letter of the alphabet followed by 'ear'
let result = string.match(regex);
console.log(result); // ["fear", "tear", "bear"]
//Another example with a range of numbers
let string = 't85 x76 c9';
let regex = /[a-z][0-9][0-9]/gi; // matches any letter of the alphabet followed by 2 numbers from 0 to 9
let result = string.match(regex);
console.log(result); //["t85", "x76"]
否定范围
就像字符集一样,甚至可以对某个范围内的字符进行否定,例如,/[^a-z]/
意思是“嘿,获取字母表中除小写字母之外的任何字符,我们真的不需要它!”。
例如:
let string = '88c foo @4c';
let regex = /[^a-z][^a-z][a-z]/gi; // matches a couple of non alphabet letter followed by a letter
let result = string.match(regex);
console.log(result); //["88c", "@4c"]
元字符
正则表达式中的字符具有非常特殊的含义。我将介绍最常用的字符。a
. \d匹配任何数字,例如 [0-9]
。b. \w匹配任何单词字符,即任何字母、数字和下划线,例如 [a-zA-Z0-9_]
。c. \s匹配空格、制表符等。d
. \t匹配制表符。e
. .句点匹配除换行符之外的任何字符。f
. \D匹配任何非数字字符,例如 [^0-9]。g
. \W匹配任何非单词字符,例如 [^a-zA-Z0-9_]。
h. \S匹配非空格字符。
量词
它们是正则表达式中具有特殊含义的符号。
a. +匹配前面的表达式1次或多次(无限制)
例如:
let string = '8 88 888';
let regex = /\d+/g; // matches a pattern of one or more digits
let result = string.match(regex);
console.log(result); //["8", "88", "888"]
//Look here:
let string = 'force 88 888';
let regex = /\d+/g; // matches a pattern of one or more digits
let result = string.match(regex);
console.log(result); //[88", "888"]
//Look at this piece of cake
let string = 'gd god good goooooooooood';
let regex = /go+d/g; // matches a pattern of one or more letter o
let result = string.match(regex);
console.log(result); //["god", "good", "goooooooooood"]
b. /*/匹配前面的表达式 0 次或多次(无限制)
let string = 'gd god good goooooooooood';
let regex = /go*d/g; // matches a pattern of zero or more letter o
let result = string.match(regex);
console.log(result); //["gd", "god", "good", "goooooooooood"]
c. ?与前面的表达式匹配 0 次或 1 次,因此前面的模式是可选的
let string = 'god good goooooooooood';
let regex = /goo?d/g; // matches god or good and the second o is optional!
let result = string.match(regex);
console.log(result); //["god", "good"]
d. ^匹配字符串的开头,并且后续正则表达式必须位于测试字符串的开头。
let string = 'force';
let regex = /^f/; // the string must start with a f
let result = regex.test(string);
console.log(result); //true
//Another example
let string = '888';
let regex = /^[0-9]/; // the string must start with a number
let result = regex.test(string);
console.log(result); //true
//Another one
let string = 'pass0999';
let regex = /^[0-9]\w+/; // the string must start with a number and followed by any word chars
let result = regex.test(string);
console.log(result); //false
例如,$匹配字符串的末尾,并且其前面的正则表达式必须位于测试字符串的末尾。
let string = 'pass0999';
let regex = /\d$/; // the string must end with a digit
let result = regex.test(string);
console.log(result); //true
f. {x}与前面的正则表达式完全匹配 x 次。
let string = 'god good goood';
let regex = /go{2}d/gi; // check for g followed by 2 letter o and then g
let result = string.match(regex);
console.log(result); //["good"]
g. {x, }匹配前一个正则表达式的至少 x 次出现。
let string = 'god good goood';
let regex = /go{2,}d/gi; // check for g followed by at least 2 letters o and then g
let result = string.match(regex);
console.log(result); //["good", "goood"]
h. {x, y}匹配前一个正则表达式至少 x 次出现、最多 y 次出现。
let string = 'god good goood gooood';
let regex = /go{2,3}d/gi; // check for g followed by at least 2 and at most 3 letters o and then d
let result = string.match(regex);
console.log(result); //["good", "goood"]
i. x|y匹配 x 或 y。
let string = 'good';
let regex = /good|bad/; // check either for 'good' or 'bad'
let result = regex.test(string);
console.log(result); //true
//And
let string = 'bad';
let regex = /good|bad/; // check either for 'good' or 'bad'
let result = regex.test(string);
console.log(result); //true
注意——如果您想使用任何特殊字符作为正则表达式的一部分,比如说您想匹配文字。或?,您必须使用反斜杠 \ 对它们进行转义。
最后快速回顾一下我们在第一篇文章中关于 Regex Basic 的内容
let regex;
//SINGLE REGEX PATTERN
regex = /abc/; //match a specific string
//FLAGS
regex = /abc/i; //match a specific string case insensitive
regex = /abc/g; //match a specific string globally
regex = /abc/gi; //match a specific string globally and case insensitive
//CHARACTER SETS AND NEGATIVE CHARACTER SETS
regex = /[abc]/; //match a specific characters set
regex = /[^abc]/; //not match a specific characters set
//RANGE OF CHARACTERS AND NEGATIVE RANGE OF CHARACTERS
regex = /[a-z]/; //match a range of characters
regex = /[^a-z]/; //not match a range of characters
//METACHARACTERS
regex = /\d/; // matches any digit
regex = /\D/; // matches any non-digit
regex = /\w/; // matches any word character, underscore included (a-z, A-Z, 0-9, _)
regex = /\W/; // matches any non-word character
regex = /\s/; // matches any white space character (\r (carriage return),\n (new line), \t (tab), \f (form feed))
regex = /\S/; // matches any non-white space character
regex = /\t/; // matches any tab
//QUANTIFIERS
regex = /[0-9]+/; //match a range of characters for one or unlimited times
regex = /[0-9]{2}/; //match a range of characters exactly 2 times
regex = /[0-9]{2,3}/; //match a range of characters from 2 to 3 times
regex = /[0-9]{2,}/; //match a range of characters from 2 to unlimited times
正则表达式的基础知识就到这里。之后会发布一篇关于更高级功能的新文章。
同时,别忘了练习这些基本技能。如果你愿意,可以去Regex101
这样的优秀网站在线练习。
我会根据大家的反馈和评论,更新本文,添加新的信息和一些关于正则表达式的算法。
如果您觉得本文有帮助,请点击💖或🦄按钮分享,希望它能帮助到更多人。欢迎在Twitter
上关注我。
代码长存,繁荣昌盛
鏂囩珷鏉ユ簮锛�https://dev.to/uptheirons78/regex-domination-to-become-an-algorithms-wizard-basic-20bd