本文最初发表在JavaScript in Plain English上。
第1部分:正则表达式速效课程解释了正则表达式背后的理论
thisisengineering(pexels.com)
照片
预期的受众:中级开发人员对 html 的强烈掌握,对 css 的某些理解以及对<<强> javascript 需要语言。
介绍
无论纪律如何,整个软件工程专业最终都面临着学习途径的挑战。当出现甚至有经验的开发人员遇到这一挑战时,它会出现在某种程度上的障碍。那一刻几乎是发现了一个新的且威胁性的四个字母的单词(尽管实际上是五个字母) - Regex 。
当我第一次遇到 REGEX (或正则表达式)时,我的经历是一场令人沮丧的斗争,以了解看起来像是一种神秘的语言,尽管它显然是明显的力量,但并没有使它的实用性变得明显。
,无论我们在Google上还是在网站的内容中搜索,我们的实用程序都很明显。当我们填写在线表格并单击提交按钮时,它的实用程序也很明显。
在提交表格中的数据之前,已对其进行验证,以确保其正确形成和/或消毒(剥夺了错误的内容)。
我们在本教程中要做什么?
我们将构建一个简单的演示单页应用程序( spa ),但具有相当复杂的基础。
本教程是三部分系列中的第一个,我们将从理论到实践,再实现完整的演示单页应用程序( spa ) 。
努力努力
如果您是正则表达式的全新,那么教程的第一部分将适合您。如果您对他们有相当的经验,那么您可以跳过本系列的第二篇文章 正则表达式的仪式:从理论到实践 。
但是,由于教程的这一部分使用我们的Web
应用程序中的数据来快速以正则表达式提供速效课程,因此您
仍然可能会发现它很有用。
在本系列第三个教程的末尾,我们将构建一个小型Web应用程序,其目的是从一串文本有效的邮政编码中提取,并在单击<<<<<<<<<<<<<<<<<<<<<<
强>验证邮政编码按钮。
图1 显示了我们完成应用程序的开放屏幕:
图。 1申请着陆页
简而言之,测试数据框架滚动以揭示一个多行字符串字符串,其中找到了有效的邮政编码。当用户单击验证邮政编码按钮时,使用正则表达式在测试数据下方显示的时,应用程序将替换 no Match 消息消息显示在右侧的框架中,并带有滚动式邮政编码匹配的滚动列表。
重置按钮将屏幕还原到其原始状态。
要意识到这个项目,我们需要深入研究正则表达式。
,但是这个应用似乎很简单。为什么将整篇文章专用于理论基础?我们不应该通过做吗?
好吧,是的,但不是真的。我们将通过做学习,但是在没有最低限度的理解依据的情况下,我们将是一场痛苦的追求。在编写此应用程序时,我们将猛击 所有的开玩笑,没有这种通行仪式,任何尝试与我们要创建的申请类似的应用程序都需要编写代码,而这些代码可能无法正常运行,而这些代码也不适用于<<强>正则表达式
直接进入 Regex 的障碍物,至少在最初,可能会感觉像撞到 霸王龙正时
对 REGEX 的彻底探索及其在 JavaScript 中的实现超出了本文的范围。这种探索很容易需要自己的过程。
但是,为了促进对我们的演示Web应用程序如何发挥作用的一些了解,我将在正则表达式的概念中快速提供速效课程实现此项目所需的必要。
只有足够的正则
要开始,我们需要定义我们的术语。到目前为止,我们只命名了我们的概念正则表达式。但是他们是什么?
什么是正则表达式?
由Mozilla开发人员网络定义
正则表达式是用于匹配字符串中字符组合的模式(正则表达式JavaScriptâ)。。
这是什么意思? 这是一个非常抽象的陈述。让我们进一步退后一步,为正则表达式设置理论上下文。
正则表达式的缩略图历史素描
数学家Stephen Cole Kleene
正则表达式的根在1951年的纸张中,标题为 Mathematician 的神经网和有限自动机 的事件表示。斯蒂芬·科尔·克莱恩(Stephen Cole Kleene)。本文定义的理论远远超出了本教程的范围,但是如果您有兴趣探索他要说的话,您可以下载纸质here(Kleene,kleene,'代表事件 em>)。
克莱恩(Kleene)理论的实际应用在1968年左右出现,当时它们被用来促进文本编辑器中的模式匹配,以及编译器的词汇分析源代码。有关此的更多信息,您可能需要咨询此article(正则表达式)。
可以说,在未来的几年中,开发了许多不同的正则表达式实现,所有这些实现都归功于其遗产归因于Unix操作系统中这些概念的出现。 表1 以下是在Wikipedia上找到的正则表达式的一些不同风味的样品( '对正则表达发动机的比较 ):
表1:REGEX的一些众所周知的口味
JavaScript中正则表达式的螺母和螺栓
在 javascript ,正则表达式以两种方式之一表示:
1.一个字面的物体。
2.用构造函数声明的对象。
对象文字符号是我们在图1 中所看到的,减去其声明。您将很快编写的代码使用符号
如下所示:
const regex = /[a-z]/g;
此表达式将在指定的测试字符串中搜索并匹配小写字母的任何实例 a a 。稍后再详细介绍。
此相同的正则表达式使用其对象构造函数,具有以下语法:
const regex = new RegExp(
‘[a-z]’, ‘g’;
);
这两个语法都相同。 是否应该使用一个时间或另一个时间? 是的,有。根据Mozilla开发人员网络:
在评估表达时会导致正则表达式的汇编。当正则表达式保持恒定时,请使用文字符号。例如,如果您使用文字符号来构建循环中使用的正则表达式,则将在每次迭代中重新编译正则表达式(Regexp javascript |mdnâ)。
您将在完整的Mozilla Developer Network article中找到有关此信息的更多完整信息。
正则表达式的解剖
我们将从更复杂的正则表达式开始,这是我们将在本教程的第2部分和第3部分中构建的有效邮政编码匹配的基础:
/^[0-9]{5}(-[0-9]{4})?$/gm
查看这条隐秘的代码行,您可能会问自己,
如果我们认为 REGEX 是我们希望匹配的字符模式的符号表示,我们可以开始对不同种类的符号字符进行分类。
我们将快速查看上面的正则表达式,逐渐挑选它,然后将其放回原处,以了解 Regex引擎的要求。我们的正则表达式的组成部分可以分解如下:
âââ€1。
2.锚
3.角色集和范围
4.量词
5.捕获小组
6.标志
所有这些组件中的所有六个组件都为我们的正则表达式发挥作用。让我们一次带他们一个。
定界符
在 javaScript对象文字符号,正则表达式在两侧都通过正向斜线界定。这些斜线之间出现的所有内容都是我们希望在测试字符串中找到匹配的模式的表示。
锚中心>
锚与测试字符串中的任何特定字符不匹配。相反,它定义了我们希望看到 Regex Engine返回的比赛的起点或终点。。
caret符号(^)表示我们正在搜索的比赛的开始。例如,如果我们想在模式开头的字母 j 的任何实例匹配,则语法将为^J
。
另一方面,美元符号( $ )表示我们正在搜索的比赛的结束。此符号在字符串模式的末端使用,并在其紧接其之前影响字符或字符集。
字符集
a 字符集是指定的字符集合,它可能是字符文字或指定的字符进程,
我们想测试特定的测试字符串。 字符集被
范围
一系列字符定义了一系列字符时,我们有一个范围。范围由一组顺序数字或字母顺序的字符组成。例如, 0 通过 9 是我们(无论如何在十进制系统中)所考虑的数字中的完整数字范围。这也将在方括号中注明,就像:
[0-9]
对于字母字符,我们还具有范围 [A-Z] 和 [A-Z] 。但是我们可以很容易地指定一系列数字,例如 [1-5] 或字母顺序的范围,例如 [a-g] 或 [a-g] 。
量词
a 量词指定匹配中所需的给定字符(或字符集中字符)的最小实例。它也可以指定
模式匹配中所需的字符的确切数量。
表2 下面显示了这些量词的一些用途:
表2:正则量词
捕获组
用括号的使用记录,捕获组设置了一个图案序列,而不是整体上采取的构成部分。用
的话,如果我们有一个像这样的捕获组
([A-G]-0[0-9][3})
我们说的是匹配任何完整的模式,该模式从 a 和 g 之间的任何大写字母开始,然后是A 连字符 strong>和 0 ,然后最终正好在 0 和 9 之间的3位数字。
在字符集中,这与普通字符集有何不同? ,除非量词立即跟随它,例如序列 [0-9 ] {3} 上面, Regex Engine 将仅匹配1个字符,该字符属于指定的范围内。
用捕获组,另一方面,整体分析了一个序列,并且必须整体上匹配。如您所见,这在我们的迷你应用中非常有用。
标志
使用标志,我们可能最容易理解迄今为止所描述的所有语法。标志对 Regex引擎的方式解析了测试字符串传递给它的方式。
javascript 正则表达式的风味有六个标志,但是我们将考试限制在您可能最常遇到的三个标志上。这些标志发生在闭合前向斜线后正则表达式的结尾处。他们是:
'ââ‖ i 不敏感的旗帜指定字母字符将
''与上层或较低匹配?案例。
'''从左到右读取测试字符串,一旦它返回了第一场比赛,退出,
'' 以外的任何比赛都忽略了。
3.上面提到的^和 $ 锚定(Judis, Multiline
- 在JavaScript正则表达式中 - >)。默认情况下,正则>搜索。
'''''''''的边界由^锚定义,
''表示字符串的开始,并表示字符串的开始,并且 $ 锚点,表示
'''''的末端。随着 m (多行)标志的附加到
'的末尾,这两个锚定义了
的开始和末端 - 一条线,而不是整个字符串。
â
好的。我知道那是很多事情,其中一些甚至可能有些混乱。这要改变。
正则撕裂
我们现在准备分析我们将要构建的Web应用程序中使用的正则表达式。让我在所有荣耀中再次看一下:
/^[0-9]{5}(-[0-9]{4})?$/gm
将其分开
让我们首先检查该表达式的最外部部分。我们正则表达式的外壳看起来像这样:
//gm
这个小片段单独说什么? 并不多,因为尚未指定模式。尽管如此,该片段为如何处理前向斜线定界器之间出现任何模式的方式设定了阶段。
使用上面的Regex标志的定义,此片段对 Regex Engine '匹配定义者之间指定的所有实例( Global)匹配),并分别考虑测试字符串的每一行(多行匹配)。 ,但是引擎现在知道如何处理定义者之间为其定义的任何模式。
模式的前半部分
这种模式的第一部分利用了我们先前学到的^锚点。让我们考虑一下图案的前半部分:
^[0-9]{5}
首先,我们有字符串锚的^开始,该声明了我们的模式的开始。接下来,我们有一个字符集在方括号中包含。该字符集完全由数字的范围 0 通过 9 。
。此范围紧随其后的是量词 {5} 。综上>将作为比赛返回。
现在,我们有正则表达式的完整上半年:
/^[0-9]{5}/gm
这是 Regex Engine 的所有内容,搜索并返回测试字符串的所有线条上的所有匹配,这从确切的5位数字的任何组合开始。
独自拍摄,我们的正则表达式的前半部分本身就是完整的,它将返回其在我们的测试字符串中找到的任何有效的5位邮政编码。
但仍然存在问题。到目前为止,我们将绕过文本中嵌入的任何有效+4邮政编码。我们正则表达式的后半部分将解决此问题。
模式的后半部分
现在让我们接近正则表达式的后半部分:
(-[0-9]{4})?$
在这里,我们遇到了一个捕获群体,这是先前解释的。 连字符,范围和量词周围的括号的存在表明该组仅作为整体进行分析。 否 捕获组的组成部分将被自行考虑。
首先,让捕获组的内容。
有时连字符只是连字符
我们从连字符开始。当A 连字符发生在划界a 字符集 的方括号内时,它表示范围,例如。 [0-9] 。当它作为捕获组的第一个字符和正方形括号外部时,它是字符字面的。因此
接下来是范围 [0-9] 。到目前为止/strong>。
在捕获组的括号之外是吗?量词,指定可以有 0 或 1 实例的实例。重要的是要注意这个?量词适用于整个捕获组,而不仅仅是其左侧的单个字符。
这是捕获组的力量。它们使得需要匹配指定的字符或字符集。因为?量词接受 0 或 1 匹配它之前的,有时被称为可选。换句话说,将返回 0 或 1 的匹配。
这种行为使 Regex引擎返回5位邮政编码或+4邮政编码的匹配项。
最后,我们有 $ aNchor ,它定义了要返回的字符串的末端。这个非常明确的指定有效的邮政编码匹配将以5位数字为单位,并具有可选连字符,然后是完全4位数字,但绝对没有按照此顺序进行。
。 将其放回原处
现在将所有东西放回原处。 图2 下面显示了我们正则表达式的整个顺序。
/^[0-9]{5}(-[0-9]{4})?$/gm
图。 2重新组装的正则表达式
现在,这个序列对我们来说应该更清楚。从左到右阅读,这是完整的正则表达式:
的含义`搜索并返回从测试字符串的所有线条上的所有匹配,这些匹配以5个数字的任何组合开始,并选择以连字符结束,并在 0的范围内恰好4位数字通过 9 。
我们有它。
一个现实世界的例子怎么样?
这是我们将为应用程序实施的内容的一个非常详尽的示例:
测试字符串
10003ASDF
10003
ASDF10003
10003-8924
您认为将从此搜索字符串中返回几场比赛? 1、2、3或4?
使用称为Regex Pal的非常有用的在线工具,我们在下面获得图3 中找到的结果:
图。 3 regexpal.com
的测试结果
在第一行, 10003 被突出显示为匹配。这是因为它符合5位邮政编码的标准。
在第二行上, asdf10003 尚未突出显示。这是因为尽管这条线有5位数字,但它们仍在 asdf 之前。因此,它不符合标准,因为匹配的字符串的开始不是需要的5位序列。
在第三行, 10003ASDF 也没有突出显示。这是因为,即使线的开头有5个数字, asdf 也遵循此序列。因此,它不符合标准,因为匹配的字符串的末端必须是开始时5位序列的最后一个数字,或者是可选连字符,然后是正好的4位数字。
最后,在第四行, 10003-8924 突出显示。这是因为它符合正好以5位数字开头的字符串的标准,并以连字符的可选顺序结束,然后恰好4位数字。
因此有2个匹配。
尽管该示例比我们在完成的应用程序中使用的示例要简单一点,但原理仍然相同。
接下来是什么?
即将到来
一旦您出现空气 。
参考
正则表达式-javascript:mdn. javascript | mdn ,
ââââ阿比亚qian23。
克莱恩,斯蒂芬·科尔。 表示神经网和有限的事件的代表
- rand Corporation 。 https://www.rand.org/content/dam/rand/pubs/research_memoranda/2008/RM704.pdf。
访问了1° 15正则表达引擎的交流。 2022年, regexp -javascript:mdn. javascript | mdn , 朱迪斯,斯特凡。 javascript正则表达式中的多行模式。 p>
-
â– https://en.wikipedia.org/wiki/Regular_expression。
ââââ阿比亚奇27。