正则表达式 ruby phone 数字
regular expression ruby phone number
我正在想办法编写我自己的正则表达式。
我列出了可行的 phone 数字和不可行的数字,并试图确保包括可行的数字,但我不知道如何完成它。
允许列表
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 号不允许的但我似乎无法弄清楚如何阻止其他的。
我应该输入最少数量的数字吗?如果是这样我该怎么做。
您似乎想将允许的 phone 号码限制为仅限法国手机 phone 号码。
您列出了有效和无效字符串,这是一个很好的起点。但是,我认为你只是想一次性写出模式,这很容易出错。
让我们遵循一种简单的方法,浏览允许的列表并为每个列表制作一个非常简单的正则表达式:
0665363636 -> ^06\d{8}$
06 65 36 36 36 -> ^06(?: \d\d){4}$
06-65-36-36-36 -> ^06(?:-\d\d){4}$
+33 6 65 36 36 36 -> ^\+33 6(?: \d\d){4}$
到目前为止一切顺利。
现在,只需将所有内容组合到一个正则表达式中,并对其进行分解(06
部分在前 3 种情况下很常见):
^06(?:\d{8}|(?: \d\d){4}|(?:-\d\d){4})|\+33 6(?: \d\d){4}$
等等。 Demo here.
作为旁注,您应该使用:
^0[67](?:\d{8}|(?: \d\d){4}|(?:-\d\d){4})|\+33 [67](?: \d\d){4}$
作为法国手机 phone 号码也可以从 07 开始。
[编辑: 发布后我发现它与@Lucas 的回答非常相似。但是,我将保留它作为替代演示文稿。]
我会尝试为每个允许的模式构造一个正则表达式,然后将它们联合起来获得一个正则表达式。
我们看到所有不以 +
开头的允许数字都有 10 位数字,因此我假设这是一项要求。如果允许不同数量的数字,那可以很容易地处理。
1.包括0665363636,排除2336653636和0065363636
我假设这意味着号码必须以数字 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
测试:
'0665363636' =~ r1 #=> 0
'2336653636' =~ r1 #=> nil
'0065363636' =~ r1 #=> nil
这似乎有效。
2。包括06 65 36 36 36,不包括06 65 36 36
另一个简单的:
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 #=> 0
'06 65 36 36' =~ r2 #=> nil
另一个明显的成功!
我们看到 06-65-36-36-36
也应该被允许。这是上面的一个很小的变体,我们不必费心创建另一个正则表达式来包含在联合中;相反,我们只是稍微修改 r2
:
r2 = /^0[1-9](?:
[\s-] # match one whitespace or a hyphen
\d{2}){4}$
/x
请注意,当字符 class.
中的连字符时,我们不必对其进行转义
测试:
'06 65 36 36 36' =~ r2 #=> 0
'06-65-36-36-36' =~ r2 #=> 0
是的!
3。包括+33 6 65 36 36 36,排除+3366536361
看来,当数字以 +
开头时,+
后面必须跟两位数,一个 space,一个数字,一个 space,然后是用 space 分隔的四对数字。我们可以把它写下来:
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
宾果!
效率
联合单个正则表达式可能不会生成最有效的单个正则表达式。您必须决定更容易的初始构建和测试以及持续维护的好处是否值得效率损失。如果效率是最重要的,您可能仍会以这种方式构建 r
,然后手动调整它。
我正在想办法编写我自己的正则表达式。
我列出了可行的 phone 数字和不可行的数字,并试图确保包括可行的数字,但我不知道如何完成它。
允许列表
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 号不允许的但我似乎无法弄清楚如何阻止其他的。
我应该输入最少数量的数字吗?如果是这样我该怎么做。
您似乎想将允许的 phone 号码限制为仅限法国手机 phone 号码。
您列出了有效和无效字符串,这是一个很好的起点。但是,我认为你只是想一次性写出模式,这很容易出错。
让我们遵循一种简单的方法,浏览允许的列表并为每个列表制作一个非常简单的正则表达式:
0665363636 -> ^06\d{8}$
06 65 36 36 36 -> ^06(?: \d\d){4}$
06-65-36-36-36 -> ^06(?:-\d\d){4}$
+33 6 65 36 36 36 -> ^\+33 6(?: \d\d){4}$
到目前为止一切顺利。
现在,只需将所有内容组合到一个正则表达式中,并对其进行分解(06
部分在前 3 种情况下很常见):
^06(?:\d{8}|(?: \d\d){4}|(?:-\d\d){4})|\+33 6(?: \d\d){4}$
等等。 Demo here.
作为旁注,您应该使用:
^0[67](?:\d{8}|(?: \d\d){4}|(?:-\d\d){4})|\+33 [67](?: \d\d){4}$
作为法国手机 phone 号码也可以从 07 开始。
[编辑: 发布后我发现它与@Lucas 的回答非常相似。但是,我将保留它作为替代演示文稿。]
我会尝试为每个允许的模式构造一个正则表达式,然后将它们联合起来获得一个正则表达式。
我们看到所有不以 +
开头的允许数字都有 10 位数字,因此我假设这是一项要求。如果允许不同数量的数字,那可以很容易地处理。
1.包括0665363636,排除2336653636和0065363636
我假设这意味着号码必须以数字 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
测试:
'0665363636' =~ r1 #=> 0
'2336653636' =~ r1 #=> nil
'0065363636' =~ r1 #=> nil
这似乎有效。
2。包括06 65 36 36 36,不包括06 65 36 36
另一个简单的:
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 #=> 0
'06 65 36 36' =~ r2 #=> nil
另一个明显的成功!
我们看到 06-65-36-36-36
也应该被允许。这是上面的一个很小的变体,我们不必费心创建另一个正则表达式来包含在联合中;相反,我们只是稍微修改 r2
:
r2 = /^0[1-9](?:
[\s-] # match one whitespace or a hyphen
\d{2}){4}$
/x
请注意,当字符 class.
中的连字符时,我们不必对其进行转义测试:
'06 65 36 36 36' =~ r2 #=> 0
'06-65-36-36-36' =~ r2 #=> 0
是的!
3。包括+33 6 65 36 36 36,排除+3366536361
看来,当数字以 +
开头时,+
后面必须跟两位数,一个 space,一个数字,一个 space,然后是用 space 分隔的四对数字。我们可以把它写下来:
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
宾果!
效率
联合单个正则表达式可能不会生成最有效的单个正则表达式。您必须决定更容易的初始构建和测试以及持续维护的好处是否值得效率损失。如果效率是最重要的,您可能仍会以这种方式构建 r
,然后手动调整它。