我正在尝试查看字符串是否与我所在国家/地区的电话号码格式匹配,这是区号(两位数字,可以或可以不以0开头,也可以在括号之间),后跟8或9位数字最后4位数字前可能有破折号。 这些是一些有效的格式:
'00 00000000'
'000-000000000'
'000 00000-0000'
'00 0000-0000'
'(00) 0000-0000'
'(000) 000000000'
到目前为止,这是我拥有的有效表达方式:
p = /0?\d{2}\s?-?\s?\d{4,5}\s?-?\s?\d{4}/
我尝试使用条件语句来查看区号是否在带有/?(\() 0?\d{2}\)|0?\d{2} \s?-?\s?\d{4,5}\s?-?\s?\d{4}/
的括号内,但是出现了(repl):1: target of repeat operator is not specified: /?(\() 0?\d{2}\)|0?\d{2} \s?-?\s?\d{4,5}\s?-?\s?\d{4}
错误。
我在这里做什么错了?
答案 0 :(得分:3)
请勿使用正则表达式验证电话号码。我敢打赌,您不希望排除那些偶尔键入2个后续空格或其他内容的地方。
相反,请过滤掉所有非数字和前导零,然后进行验证。像这样:
number.gsub(/\D+/, '').gsub(/\A0+/) =~ /\d{8,9}/
我不确定这是否能满足您的需求,但我敢打赌,您已经明白了。毕竟,[000]1234 56789
是可以理解的电话号码。
答案 1 :(得分:3)
我的回答解决了您关于conditional可选括号的想法。
从v2.0开始,Ruby支持条件语句。 syntax为(?(A)X|Y)
:如果A为true,则X为Y。
^(\()?
(?(1)\) |[ -])
)
,后接空格
|
其他:[ -]
空格或破折号。因此,带有条件的整个模式可能是
^(\()?0?\d{2}(?(1)\) |[ -])\d{4,5}[ -]?\d{4}$
请参见demo at Rubular或Regex101。进一步调整以适应您的需求。
@CarySwoveland已经回答了交替(?:\(abc\)|abc)
的替代方法,但是@AlekseiMatiushkin的回答肯定会使我的生活更轻松。
答案 2 :(得分:2)
可能有几种方法可以验证这些数字。一种方式是,我们写出所有可能的电话号码,然后为其编写一个表达式。也许类似于:
[0-9]{2,3}(\s|-)[0-9]{4,5}-?[0-9]{3,4}
re = /[0-9]{2,3}(\s|-)[0-9]{4,5}-?[0-9]{3,4}/m
str = '\'00 00000000\'
\'000-000000000\'
\'000 00000-0000\'
\'00 0000-0000\''
# Print the match result
str.scan(re) do |match|
puts match.to_s
end
此代码段仅用于显示捕获组,并且该表达式可能有效:
const regex = /[0-9]{2,3}(\s|-)[0-9]{4,5}-?[0-9]{3,4}/gm;
const str = `'00 00000000'
'000-000000000'
'000 00000-0000'
'00 0000-0000'`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log(`Found match, group ${groupIndex}: ${match}`);
});
}
如果不需要此表达式,可以在regex101.com中对其进行修改或更改。
jex.im还有助于可视化表达式。
对于()
,我们要在初始表达式中添加两个否定的后向。也许similar to this:
\(?[0-9]{2,3}\)?(\s|-)[0-9]{4,5}-?[0-9]{3,4}
答案 3 :(得分:2)
我相信您可以使用以下正则表达式。
R = /
\A # match beginning of string
(?: # begin a non-capture group
\(0?\d{2}\) # match '(' then an optional `0` then two digits then ')'
| # or
0?\d{2} # match an optional `0` then two digits
) # end the non-capture group
(?: # begin a non-capture group
[ ]+ # match one or more spaces
| # or
- # match a hyphen
) # end the non-capture group
\d{4,5} # match 4 or 5 digits
-? # optionally match a hyphen
\d{4} # match 4 digits
\z # match end of string
/x # free-spacing regex definition mode
arr = [
'00 00000000',
'000-000000000',
'000 00000-0000',
'00 0000-0000',
'(00) 0000-0000',
'(000) 000000000',
'(000 000000000',
'(0000) 000000000'
]
arr.map { |s| s.match? R }
#=> [true, true, true, true, true, true, false, false]
该正则表达式通常如下编写。
R = /\A(?:\(0?\d{2}\)|0?\d{2})(?: +|-)\d{4,5}-?\d{4}\z/
如果前导数字不能等于零,则应按以下方式进行更改。 (例如,如果'001-123456789'
和'(12)-023456789'
无效。)
R = /\A(?:\(0?[1-9]\d\)|0?\[1-9]\d)(?: +|-)[1-9]\d{3,4}-?\d{4}\z/
答案 4 :(得分:0)
除非您知道自己在非常有限的范围内工作,否则不要这样做,例如
否则,您应该使用https://github.com/mobi/telephone_number之类的健壮库(受Google libphonenumber启发)