老实说,我第一次看到正则表达式时,那是一次可怕的经历。 **它看起来像一种奇怪的外星语言!**我心想:“我花了几个月的时间学习编程,现在我必须学习这门看似超级复杂的语言!?”
然而,一旦我坐下来真正学习正则表达式,我发现它并不难,一旦你学会了语法。
我为什么还要费心学习正则表达式?
随着您开始编写越来越多的代码,它在所有类型的情况下都会派上用场,而不仅仅是有效的电话号码和电子邮件地址。在从日志中提取数据、从 API 调用中提取杂乱的 JSON 数据以及许多其他情况时,它非常有用。
我将教您如何使用 1 行代码和 1 个正则表达式来验证电话号码。 **在没有正则表达式的情况下验证电话号码成为一个令人讨厌的 leetcode 问题。**😧
为什么验证电话号码如此复杂?
假设您的网站上有一个表格,用于收集 spa 的电话号码,我的意思是,向您的订户发送短信,他们可以通过多种不同的方式提交电话号码。
所有这些都是基于美国的有效号码:
202-515-5555
202 515 5555
(202)515 5555
1 202 515 5555
2025155555
1-202-515-5555
1202-515-5555
etc
还有更多我没有列出的有效组合,但你明白了!验证每个组合,因为一个讨厌的编码问题。 *但如果你使用正则表达式来验证它,那就不行了!*😉
让我们从最简单的案例开始
我们先验证一下202-515-5555
。正则表达式的基本思想是建立一个模式来匹配一个字符串。中的图案是202-515-5555
什么?
我们从 3 位数字开始,-
然后是 3 位数字,然后是另一个-
,然后我们以 4 位数字结束。
这是要匹配的正则表达式模式的202-515-5555
样子:
^\d{3}-\d{3}-\d{4}$
让我们看看这个…
just 表示字符串的^
开头。在上面的正则表达式中,我们声明电话号码必须以 开头,\d{3}
因为^
前面有\d{3}
.
现在**\d
=> 代表单个数字**,{3}
简单意味着\d
正好重复 3 次。 这^\d{3}
意味着我们的电话号码以 3 位数字开头。
现在让我们直接跳到结尾:$
表示字符串匹配结束。\d{4}$
意味着我们的电话号码必须以 4 位数字结尾。 这有意义吗?
-
只是意味着电话号码必须在那个地方有破折号。
现在让我们从左到右阅读整个正则表达式:
^\d{3}
=> 以 3 位数字开头-
=> 后跟破折号\d{3}
=> 后接 3 位数字-
=> 后跟破折号\d{4}$
=> 以 4 位数字结尾
如有必要,请多读几遍以上部分,以确保在我们继续之前您已完全理解。
如果破折号是选项,我如何匹配电话号码?
好问题!我们如何匹配两者:202-515-5555
和2025155555
要使字符匹配可选,只需在?
其后添加一个。
这是我们新的改进匹配的样子:
^\d{3}-?\d{3}-?\d{4}$
-?
只是意味着它-
是可选的:它可能存在,也可能不存在!
让我们再次阅读整个正则表达式:
^\d{3}
=> 以 3 位数字开头-?
=>可选地后跟破折号\d{3}
=> 后接 3 位数字-?
=>可选地后跟破折号\d{4}$
=> 以 4 位数字结尾
如果有空格而不是破折号,如何匹配电话号码?
现在让我们开始匹配:202-515-5555
, 2025155555
, AND202 515 5555
-
我们可以选择-
OR ``. How do we represent this? Easy, put both-
and
inside of[...]
like this:[ -]
而不是只选择一个。
我们的新正则表达式如下所示:
^\d{3}[ -]?\d{3}[ -]?\d{4}$
现在它肯定开始看起来很陌生了!🤗
让我们分解一下:
^\d{3}
=> 以 3 位数字开头[ -]?
=>可选地后跟一个空格或破折号\d{3}
=> 后接 3 位数字[ -]?
=>可选地后跟一个空格或破折号\d{4}$
=> 以 4 位数字结尾
如何匹配我们电话号码开头的1
or1``1-
根据我们学到的知识,你能想出这个吗?
一旦您意识到1...
开头的 in 是可选的,这就有点棘手了。
让我们一步一步来…
如果您希望电话号码以1
我们添加^1
到字符串 match 开头,对吗?现在我们想在 1 之后有选择地添加破折号或空格。幸运的是,我们已经知道如何做到这一点:`[-]?'。
结合我们得到的2:^1[ -]?
将其添加到我们之前的正则表达式中,我们得到:
^1[ -]?\d{3}[ -]?\d{3}[ -]?\d{4}$
你能感觉到这里有什么不对吗? 上面的正则表达式字符串匹配必须以 开头1
,它不是可选的。 我们需要做1[ -]?
可选的。
*我们该怎么做?*由于我们在这里讨论的是多个元素:1
我们[ -]?
需要将整个事情放在(...)
创建一个组中。然后在它后面添加一个?
使整个组可选!
我知道要接受很多东西!这是它的样子:
^(1[ -]?)?\d{3}[ -]?\d{3}[ -]?\d{4}$
让我们再次分解它,现在多了一步:
^(1[ -]?)?
=>可选择以 1 开头,可选择后跟一个空格或破折号\d{3}
=> 以 3 位数字开头[ -]?
=>可选地后跟一个空格或破折号\d{3}
=> 后接 3 位数字[ -]?
=>可选地后跟一个空格或破折号\d{4}$
=> 以 4 位数字结尾
如果您还在阅读,恭喜您,您现在知道如何思考“正则表达式”了!
**还有 1 个悬而未决的问题:**如何匹配电话号码,例如:(202)515 5555
。我将把那个留给读者(*提示:*使用管道运算符(...|...)
:)。
将它们放在一起以测试实际的电话号码字符串
现在让我们把正则表达式转换成 javaScript 中的正则表达式。为此,您只需/.../
在其周围添加即可。然后使用一个名为的方法test
:
const regex = /^(1[ -]?)?\d{3}[ -]?\d{3}[ -]?\d{4}$/;
const phoneNumber = '1202-515-5555';
// test returns 'true' if there's a match and 'false' if there is not
const match = regex.test(phoneNumber);
如果您想正确学习正则表达式,这里有一个非常好的免费教程:RegexOne。这就是我学习正则表达式的方式。值得完成所有练习。
<<<<<<<<<<<< [完] >>>>>>>>>>>>