正则表达式入门课
涂伟忠
高级研发工程师
24700 人已学习
新⼈⾸单¥59
登录后,你可以任选2讲全文学习
课程目录
已完结/共 18 讲
正则表达式入门课
15
15
1.0x
00:00/00:00
登录|注册

12 | 问题集锦:详解正则常见问题及解决方案

使用断言
使用量词
使用多选结构
使用字符组
IPv6的正则表达式
见招拆招
将问题拆解成多个小问题
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789 表示IPv6地址
(?i).*? 表示匹配网页标题标签
[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+ 表示邮箱格式
(?:2[0-3]|1\d|0?\d):(?:[1-5]\d|0?\d) 表示24小时制时间格式
\d{4}-\d{2}-\d{2} 表示日期格式
\d{1,3}(.\d{1,3}){3} 表示IPv4地址
[\u4E00-\u9FFF] 表示中文字符
[1-9][0-9]{4,9} 表示QQ号码
(?<!\d)\d{6}(?!\d) 表示非数字前后的邮编
\d{6} 表示邮编
[1-9]\d{14}(\d\d[0-9Xx])? 表示第二代身份证号码
[1-9]\d{14} 表示第一代身份证号码
1(?:3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[1389])\d{8} 表示精确到前三位的手机号段
1[3-9]\d{9} 表示手机号段
[0-9A-Fa-f]+ 表示十六进制数字
[-+]?\d+(?:.\d+)? 表示正负符号和小数点可能有,也可能没有
(?:.\d+)? 表示小数点和后面的内容可能有,也可能没有
[-+]? 表示正负符号可能有,也可能没有
\d{m,n} 表示 m-n 位数字
\d{n,} 表示至少 n 位数字
\d{n} 表示 n 位数字
\d+ 或 [0-9]+ 表示连续的多个数字
\d 或 [0-9] 表示单个数字
使用锚点锁定位置
使用量词
使用多选结构
使用字符组
课后思考
正则处理问题的基本思路
IPv6地址
网页标签
邮箱
日期和时间
IPv4地址
中文字符
腾讯QQ号码
邮政编码
身份证号码
手机号码
十六进制数
浮点数
匹配正数、负数和小数
匹配数字
见招拆招
将问题分解成多个小问题
总结
常见问题及解决方案
问题处理思路
详解正则常见问题及解决方案

该思维导图由 AI 生成,仅供参考

你好,我是伟忠。今天我来给你讲一讲,使用正则处理一些常见问题的方法。

问题处理思路

在讲解具体的问题前,我先来说一下使用正则处理问题的基本思路。有一些方法比较固定,比如将问题分解成多个小问题,每个小问题见招拆招:某个位置上可能有多个字符的话,就⽤字符组。某个位置上有多个字符串的话,就⽤多选结构。出现的次数不确定的话,就⽤量词。对出现的位置有要求的话,就⽤锚点锁定位置。
在正则中比较难的是某些字符不能出现,这个情况又可以进一步分为组成中不能出现,和要查找的内容前后不能出现。后一种用环视来解决就可以了。我们主要说一下第一种。
如果是要查找的内容中不能出现某些字符,这种情况比较简单,可以通过使用中括号来排除字符组,比如非元音字母可以使用 [^aeiou]来表示。
如果是内容中不能出现某个子串,比如要求密码是 6 位,且不能有连续两个数字出现。假设密码允许的范围是 \w,你应该可以想到使用 \w{6} 来表示 6 位密码,但如果里面不能有连续两个数字的话,该如何限制呢?这个可以环视来解决,就是每个字符的后面都不能是两个数字(要注意开头也不能是 \d\d),下面是使用 Python3 语言测试的示例。
>>> import re
>>> re.match(r'^((?!\d\d)\w){6}$', '11abcd') # 不能匹配上
# 提示 (?!\d\d) 代表右边不能是两个数字,但它左边没有正则,即为空字符串
>>> re.match(r'^((?!\d\d)\w){6}$', '1a2b3c') # 能匹配上
<re.Match object; span=(0, 6), match='1a2b3c'>
>>> re.match(r'^(\w(?!\d\d)){6}$', '11abcd') # 错误正则示范
<re.Match object; span=(0, 6), match='11abcd'>
在写完正则后,我们可以通过一些工具去调试,先要确保正则满足功能需求,再看一下有没有性能问题, 如果功能不正确,性能考虑再多其实也没用。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文详细介绍了使用正则表达式处理常见问题的方法和思路。作者首先阐述了处理问题的基本思路,包括将问题分解成多个小问题、使用字符组、多选结构和量词等方法。随后,作者提出了解决方案,包括匹配数字、手机号码、身份证号码、邮政编码、腾讯QQ号码和中文字符等。对于每个问题,作者都给出了相应的正则表达式示例,并提供了一些实际运用中的注意事项和建议。文章内容涵盖了正则表达式在实际应用中的多个方面,对于需要处理文本匹配和提取的读者来说,是一份很有价值的参考资料。文章还通过具体案例分析了正则表达式书写时的思路和一些常见的错误,为读者提供了实用的技术指导。文章内容丰富,深入浅出,对读者快速了解正则表达式的应用具有很高的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《正则表达式入门课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(23)

  • 最新
  • 精选
  • 好运来
    在 https://regex101.com/ 网站上测试结果如下: 前导匹配正则表达式: [0-9A-Fa-f]{4}(?:\:(?:[0-9A-Fa-f]{4})){7} 省略前导0正则表达式: (?:0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})(?:\:(?:0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})){7}

    作者回复: 赞👍🏻

    2020-07-13
    7
    7
  • 我来也
    这不就是小抄么?😄 文中匹配ip地址时,匹配100-255时为什么是1\d\d|2[1-4]\d|25[0-5] 而不是 1\d\d|2[0-4]\d|25[0-5] 手机上不好验证,直接说了,还请同学指正。

    作者回复: 感谢指出,确实有问题,我来改一下

    2020-07-15
    2
    2
  • 青霖
    为了正则的可读性, (?:) 子组感觉还是不使用好些

    作者回复: 看情况,有时候性能要求高还是要用

    2022-06-04
    2
    1
  • [^aeiou] 有个问题是这样的: 对于这样的表达式, 是不能出现 aeiou, 这里为什么 ^ 针对的是 后面的所有字符? 而不是一个后面的一个字符的, 这个一般根据什么判断的?

    作者回复: 就是这样的写法,记住就可以了,中括号第一个是脱字符就表示里面的都不能出现。 没有不是后面一个字符的,只有后面所有字符。 另外补充一下,其实这么做不够严谨,因为不是aeiou还可能是数字等其他的,这么做的前提是你知道都是字母。

    2020-07-12
    1
  • Jock
    打卡,纪念一下,第一次完整的看完一个专栏😄

    作者回复: 点赞,感谢你的坚持和支持,😃

    2020-07-10
    1
  • 浮沉
    [-+]?\d+(?:\.\d+)?,为啥?有时候在前面,有时候在后面

    作者回复: 在前面的是分组的意思,后面的是数量

    2022-12-05归属地:四川
  • 青阳
    写不出完美的邮箱校验正则表达式,由此看来正则不是图灵完备的

    作者回复: 很多时候不要求那么严谨,只要够用就好了,正则只是个工具,能解决问题就好

    2021-10-25
  • 追风筝的人
    老师 "sadasda="adasdasd"" Python 如何处理这种? 保留“”

    作者回复: 没懂具体的要求是什么

    2020-10-27
  • 追风筝的人
    目前 QQ 号不能以 0 开头,最长的有 10 位,最短的从 10000(5 位)开始。从规则上我们可以得知,首位是 1-9,后面跟着是 4 到 9 位的数字,即可以使用 [1-9][0-9]{4,9} 来表示。

    作者回复: 没问题

    2020-10-24
  • 王九日
    匹配数字第一个里面匹配n位数字为什么不可以写成 [0-9]{n}

    作者回复: 两种都可以

    2020-09-17
收起评论
显示
设置
留言
23
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部