这是我创建的一个在JavaScript中使用的正则表达式:
var reg_num = /^(7|8|9)\d{9}$/
这是我的团队成员建议的另一个方案。
var reg_num = /^[7|8|9][\d]{9}$/
验证电话号码的规则如下:
- 电话号码应该只包含十个数字。
- 第一个数字应该是7、8或9中的任意一个。
这是我创建的一个在JavaScript中使用的正则表达式:
var reg_num = /^(7|8|9)\d{9}$/
这是我的团队成员建议的另一个方案。
var reg_num = /^[7|8|9][\d]{9}$/
验证电话号码的规则如下:
/^(7|8|9)\d{9}$/
/^[789]\d{9}$/
/^[7-9]\d{9}$/
(a|b|c)
是一个正则表达式的"或",表示 "a 或 b 或 c",虽然括号必须存在以实现或操作,但也会捕获该数字。如果要完全等效,可以使用 (?:7|8|9)
来创建一个非捕获组。
[abc]
是一个"字符类",表示"来自 a、b、c 中的任何字符"(字符类也可以使用范围,例如[a-d]
= [abcd]
)
(abc|def)
这样的事情,这种操作不能转换为字符类。[<<|>>|\]\]|\[\[]
。由于上下文,我知道该正则表达式是尝试匹配 <<
或 >>
或 [[
或 ]]
。但根据你所说,它应该匹配 <
或 >
或 [
或 ]
。如果在 []
之间使用 |
,那么括号的行为会有所不同吗? - Daniel Kaplan[...]
中使用|
。此外,在字符类中重复字符没有任何效果——字符类是一个字符列表,只会匹配其中的一个。我猜你想要一个组,它使用普通圆括号:(<<|>>|\]\]|\[\[)
。 - Bohemian你团队的建议几乎是正确的,除了那个犯的错误。一旦你找出原因,就永远不会忘记它。看一下这个错误。
/^(7|8|9)\d{9}$/
这是它的作用:
^
和 $
表示锚定匹配,断言在这些锚点之间的子模式是整个匹配。字符串只有在子模式匹配整个字符串时才会匹配成功,而不仅仅是一部分。()
表示一个捕获组。7|8|9
表示匹配7
、8
或9
中的任意一个。它使用交替来实现,即使用管道运算符|
来交替匹配。这会在交替之间回溯:如果第一个交替没有匹配成功,引擎必须在指针位置移动到交替匹配期间之前返回,以继续匹配下一个交替;而字符类可以按顺序前进。请参见禁用优化的正则表达式引擎上的此匹配:Pattern: (r|f)at
Match string: carat
Pattern: [rf]at
Match string: carat
\d{9}
匹配九个数字。\d
是一个简写元字符,可以匹配任何数字。/^[7|8|9][\d]{9}$/
看看它的作用:
^
和 $
也表示锚定匹配。[7|8|9]
是一个字符类。可以匹配列表中的任何字符7
、|
、8
、|
或9
,因此错误地添加了|
。这种匹配不需要回溯。[\d]
是一个字符类,包含元字符\d
。顺便说一句,使用字符类和单个元字符的组合是一个坏主意,因为抽象层可以减慢匹配速度,但这只是实现细节,并且仅适用于少数正则表达式实现。JavaScript 不是其中之一,但它确实使子模式稍微变长了一些。{9}
表示前面的单个结构总共重复九次。/^[789]\d{9}$/
,因为/^(7|8|9)\d{9}$/
会不必要地捕获内容,这会导致大多数正则表达式实现的性能下降(javascript可能就是其中之一,因为问题中使用了var
关键字,这很可能是JavaScript)。使用运行在PCRE上的php可以优化掉缺少回溯的问题,但我们并不在PHP环境中,所以使用类[]
而不是选择器|
会给匹配带来性能提升,因为匹配不会回溯,因此匹配和失败都比使用先前的正则表达式更快。如果你要用其他东西替换前两个示例,它们的行为会有很大不同。如果你匹配这个:
str = str.replace(/^(7|8|9)/ig,'');
你需要用空字符串替换7、8或9。
如果你匹配到这个
str = str.replace(/^[7|8|9]/ig,'');
你需要将7
或8
或9
或者竖线字符替换为空字符串。
我是通过吃亏才发现这一点的。
grep
)需要像\(7\|8\|9\)
这样的反斜杠,和/或不支持\d
简写来匹配数字。另请参见 Stack Overflow 的regex
标签信息页面,其中涵盖了许多其他常见的初学者问题。 - tripleee