利用正则表达式中的*、+可以做出怎样有用的程序?

6 2025-12-22 10:11 2025-12-22 10:11

正则表达式中的 *(零次或多次)和 +(一次或多次)是“量词”的核心,它们本身不“做程序”,但能帮你精准、高效地“捞”出文本里符合某种重复模式的内容。下面给出 6 个“开箱即用”的小工具/脚本场景,全部围绕 *+ 展开,你改 1~2 行就能套到自己的数据上。代码用 Python 示范,但正则语法在所有语言里通用。

  1. 日志切片机:把“连续重复行”压成一行
    场景:系统日志里同一条错误疯狂刷屏,只想看一次。
    关键正则:
    ^(.*)(\n\1)+$
    解释:
    .* 先把整行抓下来,\1 反向引用“同一行”,(\n\1)+ 表示“后面紧跟着至少一次换行+完全相同的行”。
    代码:
    Python
     
  1. 复制
    import re, sys
    pat = re.compile(r'^(.*)(\n\1)+$', re.M)
    print(pat.sub(r'\1', sys.stdin.read()))
     
    运行:
    cat app.log | python dedup.py
    瞬间把连续重复块压成一行。

  1. CSV 抢救器:把“含多余逗号的字段”无损还原
    场景:有人用 Excel 导 CSV,字段里本身有逗号,但没加引号,导致列错位。
    关键正则:
    ,+(?![^,]*")
    解释:
    ,+ 匹配 1 个或多个连续逗号;(?!...) 负前瞻,保证后面没有出现“引号”,即这些逗号不在合法引号字段内。
    代码:
    Python
     
  1. 复制
    import re, csv, sys
    raw = open('broken.csv').read()
    fixed = re.sub(r',+(?![^,]*")', '|', raw)   # 先把非法逗号替换成 |
    for row in csv.reader(fixed.splitlines(), delimiter='|'):
        print(row)
     
    把行重新对齐,再人工或脚本二次校验即可。

  1. 密码强度扫描器:一次性找出“连续 3+ 相同字符”的弱口令
    关键正则:
    (.)\1{2,}
    解释:
    (.) 先抓任意一个字符,\1{2,} 表示“后面再跟 2 次或更多次同一字符”。
    代码:
    Python
     
  1. 复制
    import re, sys
    pat = re.compile(r'(.)\1{2,}')
    for pw in open('passwords.txt'):
        pw = pw.strip()
        if pat.search(pw):
            print('weak:', pw)
     
    可瞬间扫出 000000、111aaa 这类弱口令。

  1. 代码统计小工具:只数“真正非空行”
    场景:想排除纯注释、空行,统计实际代码行。
    关键正则:
    ^\s*(\S+).*$
    解释:
    ^\s* 行首 0+ 空白;(\S+) 至少一个非空白;.* 后面随意。
    代码:
    Python
     
  1. 复制
    import re, glob, sys
    pat = re.compile(r'^\s*\S+.*$', re.M)
    total = 0
    for f in glob.glob('src/**/*.py', recursive=True):
        total += len(pat.findall(open(f, encoding='utf8').read()))
    print('real lines:', total)
     
    wc -l 精准得多。

  1. Markdown 章节抽取器:只抓 2~6 级标题
    关键正则:
    ^#{2,6}\s+(.+)$
    解释:
    #{2,6} 2 到 6 个井号,\s+ 至少一个空白,括号把标题文本捕获出来。
    代码:
    Python
     
  1. 复制
    import re, sys
    pat = re.compile(r'^#{2,6}\s+(.+)$', re.M)
    for title in pat.findall(sys.stdin.read()):
        print(title)
     
    可自动生成“子目录”或“文章大纲”。

  1. 网络爬虫二次清洗:把“连续 3+ 空标签”合并成一个
    场景:抓下来的 HTML 里 <p></p> 疯狂占位。
    关键正则:
    <(\w+)>(\s*)</\1>(?:\s*<\1>\s*</\1>)+
    解释:
    捕获一对空标签,再用 (?:...)+ 把“后面连续出现的一样”全部吃掉。
    代码:
    Python
     
  1. 复制
    import re, requests, sys
    html = requests.get('https://example.com').text
    cleaner = re.compile(r'<(\w+)>(\s*)</\1>(?:\s*<\1>\s*</\1>)+')
    print(cleaner.sub(r'<\1>\2</\1>', html))
     
    瞬间瘦身 HTML,再喂给 XPath/BeautifulSoup 解析更稳。

一句话总结
*+ 的“威力”在于:让你用一行表达式就能描述“重复”,从而
  • 把“肉眼要盯半天”的日志/CSV/HTML 清洗,变成一次性脚本;
  • 把“需要写几十行状态机”的弱密码/连续字段检测,缩成一条正则;
  • 把“重复冗余”的信息块合并、去重、计数,秒级完成。
只要你能把“要重复的元素”和“重复次数范围”抽象出来,*+ 就能成为最锋利的文本手术刀。

全部评论

·