正则表达式ruby电话号码

正则表达式ruby电话号码,ruby,regex,rubular,Ruby,Regex,Rubular,我正在想办法写我自己的正则表达式 我列出了一个可行的电话号码和不可行的电话号码的列表,并试图确保包括可行的电话号码,但我不知道如何完成它 允许列表 0665363636 // 06 65 36 36 36 // 06-65-36-36-36 // +33 6 65 36 36 36 不允许 06 65 36 36 // 2336653636 // +3366536361 // 0065363636 我把它弄得有点乱,我现在有这样一个: [0+][63][6 \-3][56\ ][\d{1}

我正在想办法写我自己的正则表达式

我列出了一个可行的电话号码和不可行的电话号码的列表,并试图确保包括可行的电话号码,但我不知道如何完成它

允许列表

0665363636 //
06 65 36 36 36 //
06-65-36-36-36 //
+33 6 65 36 36 36
不允许

06 65 36 36 //
2336653636 //
+3366536361 //
0065363636 
我把它弄得有点乱,我现在有这样一个:

[0+][63][6 \-3][56\ ][\d{1}][\d \-]\d{2}[\d{1} \-]\d\d? ?\-?\d?\d? ?\d?\d?$
这屏蔽了第2和第4个不允许的,但我似乎不知道如何屏蔽其他的


我应该输入最少数量的数字吗?如果是这样的话,我该怎么做。

看起来您想将允许的电话号码限制为仅限法国手机号码

您列出了有效字符串和无效字符串,这是一个很好的起点。但是,我认为您只是想一次性编写模式,这很容易出错

让我们遵循一个简单的方法,浏览允许列表,并为每个列表创建一个非常简单的正则表达式:

06653636->^06\d{8}$
066536->^06(?:\d\d){4}$
06-65-36-36-36->^06(?:-\d\d){4}$
+33 6 65 36 36->^\+33 6(?:\d\d){4}$
到目前为止还不错

现在,只需将所有内容合并到一个正则表达式中,并将其系数化一点(前3种情况下,
06
部分很常见):

^06(?:\d{8}{124;(?:\ d\d){4}{124;(?:-\ d\d){4})\+336(?:\d\d){4}$


作为旁注,您应该使用:

^0[67](?:\d{8}{124;)(?:\ d\d{4}{124;)(?:-\ d\d{4})\+33[67](?:\d\d{4}$

因为法国手机号码也可以在07年开始使用。

[编辑:发布此消息后,我发现它与@Lucas的答案非常相似。不过,我会让它作为替代演示。]

我会尝试为每个允许的模式构造一个正则表达式,然后取它们的并集来获得一个正则表达式

我们看到所有不以
+
开头的允许数字都有10位,所以我假设这是一个要求。如果允许不同的位数,则可以轻松处理

1。包括0665363636,不包括2336653636和00653636

我假设这意味着数字必须以数字
0
开头,第二个数字不能是
0
。这很简单:

r1 = /
     ^     # match start of string
     0     # match 0
     [1-9] # match any digit 1-9
     \d{8} # match 8 digits
     $     # match end of string
     /x
测试:

这似乎奏效了

2。包括066536,不包括066536

另一个简单的问题是:

r2 = /
     ^       # match start of string
     0       # match 0
     [1-9]   # match any digit 1-9 # or \d if can be zero
     (?:     # begin a non-capture group
       \s    # match one whitespace
       \d{2} # match two digits
     )       # end capture group
     {4}     # match capture group 4 times
     $       # match end of string
     /x
测试:

又一次明显的成功

我们看到
06-65-36-36-36
也应该被允许。这是上面的一个很小的变体,我们不必费心创建另一个正则表达式来包含在联盟中;相反,我们只需稍微修改
r2

r2 = /^0[1-9](?:
      [\s-] # match one whitespace or a hyphen
      \d{2}){4}$
     /x
注意,当连字符在字符类中时,我们不必转义它

测试:

对!

3。包括+3366653636,排除+3366536361

当数字以
+
开头时,
+
后面必须跟两位数字,一个空格,一个空格,然后是四对由空格分隔的数字。我们可以写下来:

r3 = /
     ^       # match start of string
     \+      # match +
     \d\d    # match two digits
     \s\d    # match one whitespace followed by a digit
     (?:     # begin a non-capture group
       \s    # match one whitespace
       \d{2} # match two digits
     )       # end capture group
     {4}     # match capture group 4 times
     $       # match end of string
     /x
测试:

搞定了

加入工会

r = Regexp.union(r1, r2, r3)
 => /(?x-mi:
         ^     # match start of string
         0     # match 0
         [1-9] # match any digit 1-9
         \d{8} # match 8 digits
         $     # match end of string
         )|(?x-mi:^0[1-9](?:
          [\s-] # match one whitespace or a hyphen
          \d{2}){4}$
         )|(?x-mi:
         ^       # match start of string
         \+      # match +
         \d\d    # match two digits
         \s\d    # match one whitespace followed by a digit
         (?:     # begin a non-capture group
           \s    # match one whitespace
           \d{2} # match two digits
         )       # end capture group
         {4}     # match capture group 4 times
         $       # match end of string
         )/ 
让我们试试看:

['0665363636', '06 65 36 36 36', '06-65-36-36-36',
 '+33 6 65 36 36 36'].any? { |s| (s =~ r).nil? } #=> false

['06 65 36 36', '2336653636', '+3366536361',
 '0065363636'].all? { |s| (s =~ r).nil? } #=> true
宾果

效率


联合单个正则表达式可能不会产生最有效的单个正则表达式。您必须决定,更简单的初始构建和测试以及持续维护的好处是否值得效率损失。如果效率是最重要的,您仍然可以这样构造
r
,然后手动调整它。

谢谢,这为我清楚地解释了思考过程。然而,当我使用这个网站时,我的大学给了我它的列表,好像它只接受第四个一样。他们提供的网站是rubular.com。编辑似乎rubular在^@Martijn上破产了这对我来说在rubular上很有效,你可能还需要使用
m
选项。Lucas提供了正确的答案。另一种方法是使用gsub清理传入的电话号码,这样号码中就不会有空格,-或+了
phone\u number.gsub(/[^\d\+]/,“”)
然后它可以像这样小:
/^(0\\+33)[1-9]\d{8}$/
r3 = /
     ^       # match start of string
     \+      # match +
     \d\d    # match two digits
     \s\d    # match one whitespace followed by a digit
     (?:     # begin a non-capture group
       \s    # match one whitespace
       \d{2} # match two digits
     )       # end capture group
     {4}     # match capture group 4 times
     $       # match end of string
     /x
'+33 6 65 36 36 36' =~ r3 #=> 0
'+3366536361'       =~ r3 #=> nil
r = Regexp.union(r1, r2, r3)
 => /(?x-mi:
         ^     # match start of string
         0     # match 0
         [1-9] # match any digit 1-9
         \d{8} # match 8 digits
         $     # match end of string
         )|(?x-mi:^0[1-9](?:
          [\s-] # match one whitespace or a hyphen
          \d{2}){4}$
         )|(?x-mi:
         ^       # match start of string
         \+      # match +
         \d\d    # match two digits
         \s\d    # match one whitespace followed by a digit
         (?:     # begin a non-capture group
           \s    # match one whitespace
           \d{2} # match two digits
         )       # end capture group
         {4}     # match capture group 4 times
         $       # match end of string
         )/ 
['0665363636', '06 65 36 36 36', '06-65-36-36-36',
 '+33 6 65 36 36 36'].any? { |s| (s =~ r).nil? } #=> false

['06 65 36 36', '2336653636', '+3366536361',
 '0065363636'].all? { |s| (s =~ r).nil? } #=> true