55 - 有效电话号码

题目

给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个 bash 脚本输出所有有效的电话号码。

你可以假设一个有效的电话号码必须满足以下两种格式: (xxx) xxx-xxxx 或 xxx-xxx-xxxx。(x 表示一个数字)

你也可以假设每行前后没有多余的空格字符。

示例:

假设 file.txt 内容如下:

987-123-4567 123 456 7890 (123) 456-7890

你的脚本应当输出下列有效的电话号码:

987-123-4567 (123) 456-7890

解答

怎么bash都要写。。😂😂

还好我最近写过git提交的脚本。。不算完全没基础。。不过还是做不出来。。

看到很多题解都有-P

grep -P '^(\d{3}-|\(\d{3}\) )\d{3}-\d{4}$' file.txt

Runtime: 8 ms, faster than 25.06% of Bash online submissions for Valid Phone Numbers.

Memory Usage: 3.2 MB, less than 28.57% of Bash online submissions for Valid Phone Numbers.

但是mac上面行不通。。只能用这种:

grep '^\([0-9]\{3\}-\|([0-9]\{3\}) \)[0-9]\{3\}-[0-9]\{4\}$' file.txt

Runtime: 0 ms, faster than 100.00% of Bash online submissions forValid Phone Numbers.

Memory Usage: 3.1 MB, less than 96.43% of Bash online submissions for Valid Phone Numbers.

反而速度更快了😂

  • grep ... file.txt,意思是在file.txt里面查找...

  • ^匹配每一行的开头,$匹配每一行的结尾

  • ()定义一个子表达式,在整体匹配玩后进行匹配

    (\d{3}-|\(\d{3}\) ) 最外层的括号,就是子表达式

    【不知道为啥) 之前一定要加一个空格,不然匹配不到】

    • \后面跟着一个特殊字符,需要转义。如\d表示匹配一个数字,等价于[0-9]

    • {3}说明匹配前一个数字,匹配3次,也就是拿到3个数字

    • -就是匹配到-

\d{3}-,说明是匹配到三个数字加一个-

  • |是“或”,匹配前面的或后面的 匹配\d{3}-,或是匹配\(\d{3}\)

  • \(,就是(,\(\)也就是匹配括号 所以\(\d{3}\)是在匹配括号内的三个数字

那么后面就都一样了

mac上行得通的含义有点难以理解,因为规则都变了

看到了一个容易理解的版本

grep -e '\(^[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}$\)' -e '\(^([0-9]\{3\})[ ]\{1\}[0-9]\{3\}-\([0-9]\{4\}\)$\)'  file.txt

Runtime: 8 ms, faster than 24.94% of Bash online submissions for Valid Phone Numbers.

Memory Usage: 3.1 MB, less than 75.00% of Bash online submissions for Valid Phone Numbers.

-e意思是,使用正则

与posix标准的区别是,这里的符号都需要用\来转义。如(),{}

这就是把两种情况分开匹配了,所以速度变慢了。

原版思路和posix的一样,前面两种情况用或来判断,后面都一样。

这个网站学正则可真是太棒了哈

Last updated

Was this helpful?