LeetCode 193. 有效电话号码
题目描述

题意分析
file.txt每行是一个待校验的电话号码,合法格式只有xxx-xxx-xxxx与(xxx) xxx-xxxx两种,每个x都是一位数字。题目已保证每行没有前后多余空白。校验的是整行格式:数字位数、括号、空格与连字符都必须精确匹配。即使某一行内部包含合法号码,只要还夹带其他字符,就不应输出。
两种格式共享后半段
三位数字-四位数字,不同的只是区号前缀。可以把前缀写成两个分支,再接上同一份后缀,用一次grep完成筛选。
解法:grep 扩展正则匹配整行
核心思路
[!blue]
用
grep -E启用扩展正则表达式,表达式的结构是^(前缀一|前缀二)公共后缀$。
[0-9]{3}-表示三位数字后紧跟一个连字符,对应无括号的区号。\([0-9]{3}\)表示左括号、三位数字、右括号,再加一个普通空格。正则中不转义的括号用于分组,因此匹配号码里的字面括号要写成\(、\)。[0-9]{3}-[0-9]{4}是两种格式共同的剩余部分,要求数字位数分别为 3 和 4。最外侧的
^、$分别要求从行首开始、在行尾结束。前缀分支先放在同一组内,这两个锚点才会同时约束两种格式。表达式使用单引号传给 shell,让其中的反斜杠和其他正则字符保持原样。
grep会按输入顺序直接输出匹配的原始行,不需要再解析或重新拼接号码。
解题步骤
- 将两种区号写成一个用
|分开的分组。- 在分组后追加公共的三位数字、连字符与四位数字。
- 用行首、行尾锚点限定整个表达式,只允许整行符合格式。
- 使用
grep -E对文件逐行筛选,原样输出命中的行。
代码实现
grep -E '^(\([0-9]{3}\) |[0-9]{3}-)[0-9]{3}-[0-9]{4}$' file.txt
复杂度分析
- 时间复杂度:$O(N)$,$N$ 是文件总字符数。正则模式长度固定,扫描输入的开销为线性。
- 空间复杂度:按逐行处理计为 $O(L)$,$L$ 是最长输入行的长度;模式本身只占常数空间,不需要把全部文件读入内存。
关键点总结
[!green]
{3}和{4}限定准确位数,不能写成任意长度的数字序列。- 括号后的普通空格属于格式,必须恰好出现一次,不能用任意空白代替。
- 分组括号不转义,输入号码里的字面括号要转义,两者用途不同。
[0-9]与grep -E的扩展正则语法匹配;不要把其他正则方言中的\d直接搬过来。
易错点总结
[!yellow]
- 漏掉首尾锚点:会接受只在局部包含合法号码的非法行。
- 将分支直接写在两个锚点之间却不分组:
^A|B$的行首只约束 A,行尾只约束 B,不能代表整行匹配 A 或 B。- 把号码中的括号当成正则分组:输入里的字面括号就不再被要求出现,匹配含义会改变。
- 省略括号后的空格,或允许多个空格:都会偏离题目要求的
(xxx) xxx-xxxx。- 令括号或连字符可选:会额外接受题目没有规定的混合格式。
- 漏写
-E:基本正则与扩展正则对分组、分支和重复次数的写法不同,不能混用。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 65. 有效数字 | 困难 | 同样验证整个字符串是否满足指定语法,原题是数值格式,本题是电话号码的两种固定格式。 |
| 468. 验证IP地址 | 中等 | 同样精确校验数字段、分隔符及整体格式,IP题还需检查每段数值范围。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!