从文本里精准 “抠“ 数据:正则表达式,让 Python 秒变文本挖掘机 处理文本时最头疼的事就是 精准提取—— 从一大段文字里找出手机号、邮箱、网址。逐字搜索太笨正则表达式regex才是正解用一串 模式 描述你要匹配的文本一次搞定查找、替换、提取、验证。一、re 模块五个核心函数import re后常用五个函数1.re.search(pattern, string)扫描整个字符串返回第一个匹配位置没有则返回 None。2.re.match(pattern, string)只从开头匹配开头不匹配就返回 None。3.re.findall(pattern, string)返回所有非重叠匹配返回列表最常用。4.re.sub(pattern, repl, string, count0)替换所有匹配repl可以是字符串或函数count限制替换次数。5.re.split(pattern, string, maxsplit0)按模式分割字符串。二、元字符正则的 字母表表示字符表格元字符说明.匹配除换行外任意单字符\d/\D数字 / 非数字等价[0-9]/[^0-9]\w/\W单词字符含下划线Unicode 下含中文/ 非单词字符\s/\S空白字符 / 非空白字符[xyz]匹配列出的任一字符[^xyz]匹配未列出的任意字符[a-z]字符范围表示数量跟在字符后面表格元字符说明*零次或多次{0,}一次或多次{1,}?零次或一次{0,1}{n}恰好 n 次{n,}至少 n 次{n,m}n 到 m 次?非贪心紧跟重复符后面尽可能少匹配默认贪心多匹配表示边界^匹配开头、$匹配结尾、\b单词边界、\B非单词边界。匹配分组x|y匹配 x 或 y(pattern)捕获分组(?Pnamepattern)命名分组\num反向引用第 num 组。三、原始字符串 r正则里满是反斜杠\d、\w强烈建议用原始字符串r...忽略转义避免语法警告和踩坑import re text abcdef123456 print(re.search(r\w, text)) # 推荐 print(re.search(\w, text)) # 会有 SyntaxWarning 警告四、实战一匹配手机号规则以 1 开头第二位是 3/4/5/7/8/9后面 9 位数字import re test [13812345678, 11456817239, 19912345678, 17138412356, 1234567890, 14752345673, 1800123456] pattern r^1[345789]\d{9}$ # 开头1 第二位数集 9位数字 结尾 for i in test: print(f{i:20}{合法 if re.match(pattern, i) else 非法})五、实战二匹配邮箱import re test [exampleexample.com, user.namesubdomain.example.co, username.com, missingusername.com, -dasdqq.com] pattern r[\w!#$%*-/?^{|}~.][\w!#$%*-/?^{|}~.]\.[a-zA-Z]{2,}$ for i in test: print(f{i:40}{合法 if re.match(pattern, i) else 非法})六、实战三匹配 0~255 之间的数字这个模式很经典分段考虑个位数 / 两位数、100~199、200~249、250~255import re test [0, 9, 50, 100, 199, 200, 255, 256, -1, 01, 001] pattern r^([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])$ for num in test: print(f{num:5}{合法 if re.match(pattern, num) else 非法})七、实战四从 HTML 标签里抠出网址用findall 分组把href...里的网址全取出来import re test link relalternate hreflangzh hrefhttps://zh.wikipedia.org/wiki/x link relalternate hreflangzh-Hans hrefhttps://zh.wikipedia.org/zh-hans/x pattern rhref(.?) # 非贪心匹配引号内的内容 for i in re.findall(pattern, test): print(i)八、实战五替换数字为对应单词re.sub的repl可以是函数每次匹配调用一次import re test I have 2 apples and 3 oranges. num_map {1: one, 2: two, 3: three, 4: four, 5: five} print(re.sub(r\d, lambda x: num_map[x.group(0)], test)) # I have two apples and three oranges.老哥收尾正则一句话\d\w\s表示字符、*?{n}表示数量、^$表示边界、()分组、r...原始串查用 search、开头用 match、全提用 findall、替换用 sub、切分用 split。下一篇是综合案例—— 把前面学的全用上写一个客户信息管理系统。有问题随时回来找老哥。