Article / 文章

LeetCode 第193题:有效电话号码

给定一个包含电话号码列表(一行一个电话号码)的文本文件 file.txt,写一个单行 bash 脚本输出所有有效的电话号码。 你可以假设一个有效的电话号码必须满足以下两种格式: 1. (xxx) xxx-xxxx 2. xxx-xxx-xxxx 其中 x 是一个数字。 你也可以假设每行前后没有多余的空格字符。

题目描述

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

你可以假设一个有效的电话号码必须满足以下两种格式:

  1. (xxx) xxx-xxxx
  2. xxx-xxx-xxxx

其中 x 是一个数字。

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

难度

简单

题目链接

点击在LeetCode中查看题目

示例

示例:

假设文件 file.txt 内容如下:

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

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

987-123-4567
(123) 456-7890

解题思路

方法一:使用grep命令和正则表达式

这个问题本质上是一个正则表达式匹配问题,我们可以使用grep命令来匹配符合要求的电话号码格式。

关键点:

  1. 使用 grep 命令搜索符合模式的行
  2. 使用正则表达式描述两种有效的电话号码格式
  3. 使用 -E 参数启用扩展正则表达式

时间复杂度:O(n),其中 n 是文件的行数 空间复杂度:O(1),只需要常数额外空间

方法二:使用sed命令筛选

除了grep,我们还可以使用sed命令来筛选符合条件的行。sed命令更适合进行文本替换操作,但也可以用于打印符合条件的行。

关键点:

  1. 使用 sed 命令的 -n 参数抑制默认输出
  2. 使用 p 命令打印符合条件的行
  3. 使用正则表达式描述两种电话号码格式

时间复杂度:O(n),其中 n 是文件的行数 空间复杂度:O(1),只需要常数额外空间

方法三:使用awk命令筛选

awk是一个功能强大的文本处理工具,特别适合处理按行和列组织的数据。我们可以使用awk的正则表达式匹配功能来筛选符合条件的行。

关键点:

  1. 使用 awk 命令的模式匹配功能
  2. 只打印匹配指定正则表达式的行

时间复杂度:O(n),其中 n 是文件的行数 空间复杂度:O(1),只需要常数额外空间

代码实现

方法一:使用grep命令和正则表达式

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

方法二:使用sed命令筛选

sed -n -E '/^(\([0-9]{3}\) [0-9]{3}-[0-9]{4}|[0-9]{3}-[0-9]{3}-[0-9]{4})$/p' file.txt

方法三:使用awk命令筛选

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

性能分析

各方法的性能对比:

方法 执行用时 内存消耗 特点
方法一 0 ms 3.0 MB grep命令简洁高效
方法二 0 ms 3.0 MB sed命令功能强大
方法三 4 ms 3.1 MB awk命令处理更复杂的情况更适合

补充说明

代码亮点

  1. 所有方法都使用了简洁的单行命令
  2. 正则表达式设计合理,准确匹配两种电话号码格式
  3. 利用 -E 参数使用扩展正则表达式,使表达式更简洁

正则表达式解释

  • ^$:匹配行的开始和结束,确保整行都符合格式
  • \([0-9]{3}\):匹配(xxx)格式,其中xxx是三个数字
  • [0-9]{3}-[0-9]{3}-[0-9]{4}:匹配xxx-xxx-xxxx格式
  • |:或运算符,匹配两种格式之一

常见错误

  1. 忘记使用 ^$ 锚点,导致部分匹配也被输出
  2. 正则表达式中括号的转义处理不当
  3. 没有正确处理空格字符,特别是在第一种格式中的空格
  4. 使用基本正则表达式(没有 -E 参数)导致某些特殊字符需要额外转义

相关题目