有效电话号码

标签: None

难度: Easy

给定一个包含电话号码列表(一行一个电话号码)的文本文件 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

Submission

运行时间: 8 ms

内存: 3.1 MB

# Read from the file file.txt and output all valid phone numbers to stdout.
egrep '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt

Explain

这个题解使用了 egrep 命令,也就是 grep 命令的扩展正则表达式版本。它定义了一个正则表达式模式来匹配有效的电话号码格式。^ 表示行的开始,$ 表示行的结束。[0-9]{3} 匹配任意三个数字。\( 和 \) 用来匹配括号字符。| 表示或者,用来匹配两种格式 (xxx) xxx-xxxx 或 xxx-xxx-xxxx。最后将匹配到的有效电话号码输出。

时间复杂度: O(n)

空间复杂度: O(1)

# 从文件 file.txt 中读取内容,将所有匹配的有效电话号码输出到标准输出
egrep '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt
# ^ 表示行开始
# (\([0-9]{3}\) |[0-9]{3}-) 匹配两种格式的区号:(xxx) 或 xxx-
# [0-9]{3}-[0-9]{4} 匹配 xxx-xxxx 的后 7 位数字
# $ 表示行结束

Explore

在正则表达式中,'^' 符号用于指定必须从一行的开头开始匹配,而 '$' 符号指定匹配必须在行的末尾结束。这样使用可以确保整行正好符合我们的匹配模式,没有多余或缺少的字符。在电话号码匹配的场景中,使用 '^' 和 '$' 可以避免匹配到长于或包含额外字符的行,确保每一行严格符合电话号码的格式。

在正则表达式中,某些字符如圆括号 '(' 和 ')' 是特殊字符,用于分组表达式的部分内容。因此,如果要匹配这些字符的字面值,需要使用反斜杠 '\' 进行转义,使其失去特殊意义,变为普通字符。这样,在匹配电话号码中的括号时,使用 '\(' 和 '\)' 确保正则表达式理解为要查找实际的括号字符,而不是进行分组。

'|' 是正则表达式中的逻辑或运算符,用来表示匹配此符号左侧或右侧的表达式。在这个例子中,'|' 用于分隔两种不同的电话号码格式:带括号的区号 '(xxx)' 和不带括号的区号 'xxx-'。这样 '|[0-9]{3}-' 允许正则表达式匹配两种格式中的任意一种,从而增加了表达式的灵活性和实用性。

'[0-9]{3}' 在正则表达式中表示匹配三个连续的数字(0至9)。方括号 '[0-9]' 定义了一个字符类,匹配任何一个数字字符。而 '{3}' 是一个量词,指定前面的模式部分(即数字)出现恰好三次。这种写法简洁且直观,允许精确控制匹配特定数量的字符,对于匹配电话号码中的固定长度数字非常有用。