示例成品 · 平台演示,按左边这组点选真跑出来的
直接可用:
```python
import re
PHONE_RE = re.compile(r'(?<![-0-9])1[3-9][0-9](?:-[0-9]{4}-[0-9]{4}|[0-9]{8})(?![-0-9])')
text = "联系电话:138-1234-5678,另一个 15900001111,坏号 138-1234-56789 不取。"
print(PHONE_RE.findall(text))
# ['138-1234-5678', '15900001111']
```
解释人话:
- 支持两种格式:`138-1234-5678` 和 `13812345678`
- `1[3-9][0-9]`:手机号前三位,1 开头,第二位 3-9
- `(?:-[0-9]{4}-[0-9]{4}|[0-9]{8})`:后面要么是 `-1234-5678`,要么是连续 8 位数字
- 头尾的 `(?<![-0-9])` / `(?![-0-9])`:前后不能再是数字或横杠,防止把 `138-1234-56789` 或 `138-1234-5678-999` 这种截断成假号码
注意:这里用 `[0-9]` 而不是 `\d`,因为 Python 里 `\d` 可能会匹配到非 ASCII 数字。
提取出来后如果要去掉横杠统一入库:
```python
phone.replace('-', '')
```
这个正则做的是格式和边界过滤,不是运营商号段白名单;你给的 `138`、`159`、`186` 开头都能正常提出。
点左边「开工 · 直接出成品」,出一份你自己的版本(文字免费)