掌握正则表达式成为算法向导(基础版)

2025-06-10

掌握正则表达式成为算法向导(基础版)

在本文中,我想仔细探讨一下我在学习编程时遇到的最奇怪的论点之一:正则表达式。
每当我使用正则表达式时,我都感觉自己就像站在耶哥蕊特面前的琼恩·雪诺,听她说“你什么都不知道,琼恩·雪诺”
可能是因为每次接触正则表达式,我都觉得自己对它一无所知☹。似乎总有一些新东西需要学习,而我却错过了或不知道。
我想,任何一位超级程序员第一次接触正则表达式时,都会和我有同样的感受。

在FreeCodeCampCodewars上练习了大量算法之后,我可以告诉你,正则表达式一开始确实很难理解,但在解决 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]/表示“嘿,在字符串中查找abc
”。 语法:/[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]/意思是“查找字符串中除abc之外的字符” 。
示例:

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]/表示“嘿,在字符串中查找从ac的字符范围” 。它将搜索 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
PREV
创建 RawJS 之后,我再也没有碰过 React。
NEXT
我迷茫了。能给一个有两年经验的普通程序员一些建议吗?