用正则思考
#javascript #编程 #regex

这不是一个完全初学者的职位。假定对正则熟悉的基本熟悉程度(或至少一个关于什么是正则是一个含糊的想法)。理想的读者将是至少过去试图学习或与正则斗争的人。

害怕

正则表达式可能令人生畏,有充分的理由。
例如,以下是有效电子邮件的正则表达式:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

Source

Alt Text

但是,好消息是,无论您是您的用例 - 堆栈溢出的某个地方已经问过,并且已经(在大多数情况下)已经有一个接受的答案。

Image description

此外,大多数时间,正则是在NPM软件包和验证库中隐藏或抽象的,因此我们通常不必担心尝试自己写一封。

虽然这不一定是不好的,但这使我们能够复制粘贴的大部分正则等级,而无需推理它,甚至尝试对其进行基本的理解。

简而言之

这篇文章的目的是为了消除一些最初的恐惧,使您能够更好地理解您的正则表达式。

该帖子分为以下5个部分:

  • JS中的正则表达式快速刷新
  • (不完整的)语法参考 - 足以满足最常见的用例和编程问题
  • 在构建正则时期时如何构建思维过程的演练
  • 测试我们的理解的一个例子
  • 巩固我们的理解的另一个例子

JavaScript中的正则表达式

  • str.split(re)MDN
  • str. -Match(re)MDN
  • str.replace(re)MDN
  • re.test(str)MDN
  • re.exec(str)MDN

(不完整的)语法参考

  • .匹配任何字符
  • ?零或一次
  • *零或更多次
  • + - 一次或多次
  • ^锚定在开始,$锚定在末端

    • /^$/-匹配启动和结束
    • 之间的任何地方都无法匹配
  • []字符类

    • 仅表示 1 字符
    • 可以使用+*匹配或{}以获取确切的数字,或者我们可以重复类似的字符集
      • [a-z][a-z]匹配2个字母(虽然不建议)
    • 内部的顺序是无关紧要的 - 正如整个字符所设置的一个字符
      • [a=z\s][\sa-z]是相同的
  • (a|b)匹配A或B

  • ()捕获组

    • 也用于创建组
  • (?:)-非捕获组

  • \d[0-9] digit

  • \w[A-Za-z0-9]-任何单词

    • 范围可以是任何东西,例如[a-e][0-4]等。
  • \s[ \t\r\n\f] - whitespace

  • \b-单词边界

    • 主题中每个单词的边界本身与单词匹配
    • 如果它是较大的单词的一部分,或者没有匹配,或者在它之前和之后都有某些东西
    • 示例:
ok/ /* matches both ok and okie */
/ok\b/ 
/* matches only ok as there is no word boundary after ok i.e. between ok and ie */

建立思维过程

  1. 要匹配正则是从完整的字符串开始。
  2. 然后慢慢开始更换您所知道的东西。
  3. 添加最终触摸和锚。

构建思维过程:示例

  • jatin@example.com
  • 步骤
    • 匹配正则刚好从完整的字符串开始
      • "jatin@example.com".match(/jatin@example.com/);
    • 然后慢慢开始更换您知道的东西
      • jatin,示例和com可以用[a-z]+替换,因为所有这些都必须是一个或多个字符
      • "jatin@example.com".match(/[a-z]+@[a-z]+.[a-z]+/);
    • .是指正则表达式中的任何角色,因此jatin@example.com或其他任何其他角色代替.也将匹配,因此我们需要逃脱并确切地匹配它
      • "jatin@example.com".match(/[a-z]+@[a-z]+\.[a-z]+/);
    • 现在让我们进行微调,现在jatin@example.comsdasd也将匹配,让我们放一些TLD(顶级域)检查和锚点以进行起始和结束
      • 没有$锚,它仍然会产生部分匹配,这也是不正确的(将锚放在下面后,无效的URL将不再匹配)
      • "jatin@example.comsdasd".match(/^[a-z]+@[a-z]+\.(com|net|edu|org)$/);

建立思想过程:另一个例子

  • [复习捕获组] - 当我们想返回正则匹配的部分时,使用捕获组
  • 示例:就像我们可以有一个大义务以匹配邮寄地址,但我们添加了邮政编码,城市等的捕获组。
  • 如何
    • 我们可以通过包裹括号来做到这一点,就像那样简单
  • 问题声明:从邮寄地址获取城市,街道,州和邮编

    • "120 east 4th street, Juneau, AK 99705"
    • 从完整的字符串开始
      • "120 east 4th street, Juneau, AK 99705".match(/120 east 4th street, Juneau, AK 99705/);
    • 很快我们可以到达工作正则
      • "120 east 4th street, Juneau, AK 99705".match(/[\w\s]+,\s?\w+,\s?[A-Z]{2}\s[\d]{5}/);
    • 现在,我们需要捕获我们想要的特定组 - 就像包装()一样简单
      • "120 east 4th street, Juneau, AK 99705".match(/([\w\s]+),\s?(\w+),\s?([A-Z]{2})\s([\d]{5})/);
    • 最终放置锚和修饰符 "120 east 4th street, Juneau, AK 99705".match(/^([\w\s]+),\s?(\w+),\s?([A-Z]{2})\s([\d]{5})$/ig);
  • 这些匹配组通过匹配功能

  • 返回
  • 警告 **

    • 如果您使用()进行分组
    • 避免
      • 使其成为非捕获组 (?:)
      • 现在,这将用于分组,但不会返回该组作为匹配组!

您也可以找到两个示例here

分开的话

正则表达式是在武器库中拥有的强大工具。希望您现在对正则表达式有更好的理解,并且可以至少开始推理它们。