直接用^\d+\.\d+\.\d+\.\d+$会漏掉大部分IP,因为日志中IP从不独占一行,而是嵌在行内;需用\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.等精确模式配合单词边界\b匹配独立IPv4字段,避免回溯爆炸。

为什么直接用 ^\d+\.\d+\.\d+\.\d+$ 会漏掉大部分 IP?
日志里的 IP 几乎从不独占一行,而是混在时间戳、路径、状态码之间。比如 192.168.1.100 - - [10/Jan/2024:08:32:15 +0000] "GET /api/v1/user HTTP/1.1" 200 1234 —— 这种情况下,^ 和 $ 完全失效。
真正要匹配的是「作为独立字段出现的 IPv4 地址」,得靠单词边界和非贪婪锚定:\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b,但还得防住像 999.999.999.999 这种非法值。
Sublime Text 查找框里怎么写才能又快又准?
千万行日志下,正则引擎性能敏感。别用 .* 前置或后置模糊匹配,它会触发回溯爆炸;也别开「Match Whole Word」——它和 \b 冲突,反而降低命中率。
- 启用「Regular Expression」模式(Alt+R 或右下角图标)
- 查找输入:
\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b - 替换留空,然后用「Find All」(Ctrl+Shift+F)一次性选中所有匹配项
- 再按 Ctrl+C 复制,粘贴到新标签页即得纯 IP 列表
提取后去重并统计频次,别在 Sublime 里硬刚
Sublime 没内置排序或计数功能,强行用「Sort Lines」+ 手动合并只会卡死。更现实的做法是导出后交给命令行或 Python 处理:
- 复制全部 IP 到文件
ips.txt - Linux/macOS 下快速去重计数:
sort ips.txt | uniq -c | sort -nr - Windows PowerShell:
Get-Content ips.txt | Sort-Object | Group-Object | Sort-Object Count -Descending - 若需保留原始顺序去重(如首次出现 IP 列表),Python 一行搞定:
list(dict.fromkeys(open("ips.txt").read().split()))
IPv6 怎么办?Sublime 能不能一起抓?
能,但代价高。IPv6 正则极长(如 [0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}),且和 IPv4 规则无法简洁 OR 合并(| 会显著拖慢匹配速度)。实际日志中 IPv6 出现比例低,建议分两轮处理:
- 先跑 IPv4 正则,保存结果
- 再开新查找:关闭「Regular Expression」,用字面量
:筛出含冒号的行,人工确认是否为 IPv6 格式(比如2001:db8::1),再针对性补正则 - 注意:Sublime 默认不支持
(?i)忽略大小写修饰符,IPv6 中的a-f必须显式写成[0-9a-fA-F]
真正麻烦的不是写对正则,而是日志格式不统一——Nginx、Apache、自研服务输出的 IP 字段位置可能差两列。抽之前先花三分钟看前 20 行样本,比调十次正则更省时间。


















