我需要编写一个正则表达式,用以下条件验证电话号码:
如果输入少于7位,则按原样返回。否则,如果第一个字符是1或0,请删除它。如果我们还没有返回,并且数字小于10位,请返回它。如果大于等于10位,则返回最后7位。
这是从编码的条件语句转换而来的性能关键代码,因此理想情况下可以在单个regex中完成。我设法拼凑了一些东西,使我接近,但我有一些困难,满足所有的标准,而不是进一步打破东西。
(因为这里有很多东西,所以空格只是用来分隔东西)。
var pattern = Pattern.compile("(?<=\A[01]?) ([0-9]{1,9}) (?![0-9]) | (?:[01]?) (?<=\A[01]?) (?:[0-9]{3,}) ([0-9]{7}) (.*)", "$1$2");
return pattern.replaceAll(phoneNum);
它通过了我给它的所有测试字符串,除了它不会像应该的那样删除0或1,如果它们作为长度为7+的字符串的第一个字符存在的话。
// Returns input as-is if fewer than 7 digits
555123 --> 555123 Success
// If 7+ digits remove the first character if it is a 1 or 0
1234567 --> 234567 Failure, returned 1234567
// If we haven't returned yet and the number is < 10 digits, return
5551212 --> 5551212 Success
// If it's >= 10 digits, return the last 7
5551234567 --> 1234567 Success
3条答案
按热度按时间mkshixfv1#
下面是if版本,正如注解中所建议的,我还将您的测试添加为单元测试:
kkih6yb82#
java不是我的强项,但正如人们提到的,regex可能不是解决您问题的正确方法。如果您仍然对正则表达式感兴趣,我认为以下内容涵盖了您的所有标准:
查看在线演示
^
-开始串ancor。(?:
-打开非捕获组。(?=\d{7,9}$
-当有7-9位数字到字符串末尾ancor时,一个肯定的向前看来Assert位置。[01]?
-可以选择捕获0或1。|
-或:\d*
-捕获尽可能多的数字,但直到:(?=\d{7}$)
-正向向前看7位直到结束字符串ancor。|
-或者:不匹配。)
-关闭非捕获组。(\d+$)
-捕获第一个捕获组中的所有剩余数字,直到结束字符串ancor。6za6bjd03#
用lambda替换all就足够了,缺点是lambda有点慢,但是regex更快。它更易于维护,当然对于现实世界的业务逻辑来说。只需将结果计时在一个微基准中。
您的测试用例应该保持为单元测试,因为这样的业务规则往往会“稍微”改变——特别是如果您喜欢单个regex的话。