2012-03-21 137 views
65

这里是一个正则表达式我创建在JavaScript中使用:正则表达式中方括号和括号之间的区别是什么?

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

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

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

的规则是验证电话号码:

  • 它应该只有10个数字。
  • 的第一个号码被认为是任何的7,8或9
+13

你的团队成员应该阅读一个基本的正则表达式教程。第二对括号是多余的,'|'是错误的 - 那个正则表达式会验证字符串'“| 123456789”'。 – 2012-03-21 09:51:32

+0

'[\ d]'也是荒谬的,直接使用'\ d'。因为'\ d'是[1234567890]' – Eddy 2016-07-19 06:18:11

回答

74

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

  • /^(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)的东西,它不会翻译成字符类。

+24

'(7 | 8 | 9)'和'[789]'的缩写,并不等同,因为第一个是捕获,而后者不是。 '(?:7 | 8 | 9)'相当于另一方面(我想你当然知道......)。 – hochl 2012-03-21 09:55:28

+0

我看到这个正则表达式:'[<<|>> | \] \] | \ [\ []''。由于上下文,我知道正则表达式试图匹配'<<' or '>>或'[['或']]'。但是根据你所说的,它应该与'<' or '>'或'['或']'匹配。如果在'[]'之间使用'|',那么括号的行为是否有所不同? – 2017-11-14 20:39:29

+1

@DanielKaplan不要在字符类[']内使用'|',除非你想匹配管道字符本身。在字符类中复制字符也没有作用 - 字符类是字符列表,并且将恰好匹配其中的一个字符。我的猜测是你想要一个*组*,它使用正常的圆括号:'(<<|>> | \] \] | \ [\ [)' – Bohemian 2017-11-14 21:35:43

8

前2个例子的行为非常不同,如果你正在用某物替换它们。如果您在此匹配:

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

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

如果您在本

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

匹配你将取代789或竖线!!!!由空字符串。

我刚刚发现困难的方式。

+3

欢迎来到SO!替换或匹配,这显然是错误的。很多人犯了这个错误,而且他们通常会逃避 - 多年来,有时候 - 因为他们的输入字符串从不包含管道('|')。 – 2013-06-20 19:15:22

40

您的团队的建议是差不多没错,除了他犯的错误。一旦你找到原因,你将永远不会忘记它。看看这个错误。

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

此作用:

  • ^$表示锚定的比赛,它断言在这些锚定件之间的子模式是整个匹配。只有在子模式与其全部匹配时,字符串才会匹配,而不仅仅是一个部分。
  • ()表示捕获组
  • 7|8|9表示匹配7,89中的任一个。它通过变更来做到这一点,这是管道运营商|所做的 - 在变更之间交替。这在交替之间回溯:如果第一次交替不匹配,那么在交替匹配期间指针位置移动之前,引擎必须返回,以继续匹配下一次交替;角色类别可以按顺序前进观看这场比赛对正则表达式引擎禁用优化:
Pattern: (r|f)at 
Match string: carat 

alternations

Pattern: [rf]at 
Match string: carat 

class

  • \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}$/捕获不必要强行对大多数正则表达式实现性能下降(恰好是一个考虑的问题使用关键字var代码,这可能是JavaScript的)。使用在PCRE上运行的来进行preg匹配会优化缺乏回溯,但是我们也不在PHP中,所以使用类[]而不是|可以提供性能奖励,因为匹配不会回溯,因此两个匹配并且比使用以前的正则表达式失败得更快。

+1

只是出于兴趣,截图来自哪个程序? – 2015-10-12 07:56:40

+5

http://regex101.com – Unihedron 2015-10-12 11:45:34

相关问题