正则表达式中的方括号和括号有什么区别?


101

这是我创建要在JavaScript中使用的正则表达式:

var reg_num = /^(7|8|9)\d{9}$/

这是我的团队成员建议的另一个。

var reg_num = /^[7|8|9][\d]{9}$/

规则是验证电话号码:

  • 它应该只有十个数字。
  • 第一个数字应该是7、8或9中的任何一个。

Answers:


124

这些正则表达式是等效的(出于匹配目的):

  • /^(7|8|9)\d{9}$/
  • /^[789]\d{9}$/
  • /^[7-9]\d{9}$/

说明:

  • (a|b|c)是一个正则表达式“ OR”,表示“ a或b或c”,尽管OR所必需的括号也可以捕获该数字。严格来说,您可以编写代码(?:7|8|9)使其成为一个捕获组。

  • [abc]是“字符类”,表示“来自a,b或c的任何字符”(字符类可以使用范围,例如[a-d]= [abcd]

这些正则表达式相似的原因是,字符类是“或”的缩写(但仅适用于单个字符)。另外,您还可以执行(abc|def)不转换为字符类的操作。


30
(7|8|9)并且[789]不是等效的,因为前者正在捕获,后者则没有。(?:7|8|9)另一方面将是等效的(我想您当然知道...)。
hochl 2012年

我看到此正则表达式:[<<|>>|\]\]|\[\[]。由于上下文的原因,我知道正则表达式试图匹配<<or >>[[or ]]。但是从您所说的来看,它应该与<or >[or 匹配]。如果在|之间使用[],括号的行为会有所不同吗?
Daniel Kaplan

1
@DanielKaplan不在|字符类中使用[...],除非您要匹配管道字符本身。同样,在字符类中复制字符也不起作用-字符类是一个字符列表,将与它们中的一个完全匹配。我的猜测是,你想要一个,使用正常的圆括弧:(<<|>>|\]\]|\[\[)
波西米亚

57

您团队的建议几乎是正确的,除了所犯的错误。一旦找到原因,您将永远不会忘记它。看一下这个错误。

/^(7|8|9)\d{9}$/

这是做什么的:

  • ^$表示锚定匹配,它断言在这些锚定件之间的子模式是整个匹配。仅当子模式与整个字符串匹配时才匹配字符串,而不仅仅是部分匹配。
  • ()表示捕获组
  • 7|8|9表示匹配的任一789。它通过交替进行操作,这是管道操作员|所做的工作–在交替之间交替进行。在交替之间回溯:如果第一个交替不匹配,则引擎必须在交替匹配期间指针位置移动之前返回,以继续匹配下一个交替;而角色类可以顺序前进。在禁用优化的正则表达式引擎上查看此匹配项:
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} 表示先前的单个构建体总共重复了9次。

最佳正则表达式为/^[789]\d{9}$/,因为/^(7|8|9)\d{9}$/不必要的捕获会导致大多数正则表达式实现的性能下降(碰巧是一个,考虑到问题var在代码中使用关键字,这可能是JavaScript)。指某东西的用途在PCRE上运行以进行预匹配的对象可以优化回溯的缺失,但是我们也不在PHP中,因此使用类[]而不是轮换可以|提高性能,因为匹配不会回溯,因此匹配和失败都比使用您的更快以前的正则表达式。


6
只是出于兴趣,该屏幕截图来自哪个程序?
Mystery Guest先生

12

如果您通过某种方式替换它们,则前两个示例的行为会大不相同。如果您对此进行匹配:

str = str.replace(/^(7|8|9)/ig,''); 

您将用空字符串替换7或8或9。

如果您与此匹配

str = str.replace(/^[7|8|9]/ig,''); 

您将替换7or 89OR垂直栏!!!!由空字符串组成。

我只是很难发现这一点。


6
欢迎来到SO!替换或匹配,这完全是错误的。很多人都犯了这个错误,并且通常会花很多时间才能避免这个错误,有时是因为他们的输入字符串从未碰巧包含管道(|)。
艾伦·摩尔2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.