正则表达式这个东西确实有点复杂,要是每次都从头写挺麻烦的,所以就把平时会用到的都记录到这儿。
-
在线正则表达式测试以及性能分析工具:https://regex101.com/
-
有一个搜索正则非常棒的方法,直接在
google输入类似regex email等内容,出来的第一条会是谷歌提供的格式化的搜索结果。 -
正则表达式引擎的实现方式:
DFA自动机(Deterministic Final Automata确定型有穷自动机): 时间复杂度是线性的,更加稳定,但是功能有限
NFA自动机(Non deterministic Finite Automaton不确定型有穷自动机): 时间复杂度不稳定,有时很好有时很差,大多数编程语言使用的是NFA,由于不稳定,所以对于复杂的语句我们有时候需要优化一下。
-
正则匹配是一个CPU密集型的任务,如果出现CPU被占满性能依然不够的情况,可以用上述性能分析网站看是否有灾难性回溯的出现,如果没有,可以考虑换一种更适合业务场景的算法,例如敏感词过滤推荐使用DFA算法,最后,实在不行,只有提高CPU了。
| 字符 | 说明 |
|---|---|
| ^ | 匹配字符串开始的位置 |
| $ | 匹配字符串结束的位置 |
| * | 零次或多次匹配前面的字符或子表达式,例如,zo*匹配z和zoo |
| + | 一次或多次匹配前面的字符或子表达式,例如zo+匹配zo和zoo但不匹配z |
| ? | 零次或一次匹配前面的字符或子表达式,例如zo?匹配z和zo但不匹配zoo |
| \w | 匹配所有非特殊字符 |
| \W | 匹配所有特殊字符 |
| [] | 包括里面的字符 |
| [^] | 排除里面的字符 |
| [^\W] | 排除所有的非特殊字符 |
| [\w]+或\w+ | 匹配数字、字母以及下划线(即非特殊字符) |
| [\w-+]+ | 匹配数字、字母、下划线以及-、+ |
| {n} | 刚好匹配n次,例如 o{2}与”Bob”中的”o”不匹配,但与”food”中的两个”o”匹配 |
| {n,} | 至少匹配n次 |
| {n,m} | 匹配至少n次,至多m次。不填m表示不限最大数量 |
| . | 匹配除”\n”之外的任何单个字符,要匹配任意字符应该使用([\s\S]*),这种方法包括了换行符的 |
| .* | 匹配任意字符,最长匹配(贪婪型的,比如(.)/就表示遇到最后一个/就结束) |
| .*? | 匹配任意字符,最段匹配(贪婪型的,比如(.)/就表示遇到第一个/就结束),包括换行符就是([\s\S]*?) |
| ?= | 零宽断言,先从要匹配的字符串中的最右端找到第一个匹配项,然后再匹配前面的表达式,例如[a-z](?=ing)可以匹配cooking singing中的cook与sing,.(?=ing)可以匹配cooking singing中的cooking sing而不是cook,同样,这样的表达式可以匹配多次,适合找前缀和后缀的情况 |
| \d | 匹配一个数字 |
| \n | 匹配一个换行符 |
| \f | 匹配一个换页 |
| \r | 匹配一个回车符 |
| \t | 匹配一个制表符 |
| \v | 匹配一个垂直制表符 |
| \s+ | 匹配一个或多个空白 |
| | | 或者,最好把两个条件都用小括号括起来,例如(a|b) |
| () | 在匹配的时候没什么作用,主要用于程序提取匹配到的字符串 |
| (?i) | 后面的内容忽略大小写 |
常用正则表达式
正则表达式收藏网站
https://github.com/geongeorge/i-hate-regex
匹配URL/IP地址
# 匹配URL,来自stackoverflow.com
https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)
# 上述表达式的不含http版本
[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)
# 但是上面的还是有一点缺陷,比如会认为,..abc这种是正确的,所以在stackoverflow找到另外一个,现在最常用的是下面这个
^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([-.]{1}[a-z0-9]+)*\.[a-z]{2,6}(:[0-9]{1,5})?(\/.*)?$
# 匹配IPv4地址
^(?=.*[^\.]$)((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.?){4}$
# 获取url中的domain和request
(https*:\/\/)*(?<domain>.*?)\/(?<request>.*)
# 获取URL中各个字段
^(?:(\w+):\/\/)?(?:(\w+):?(\w+)?@)?([^:\/\?#]+)(?::(\d+))?(\/[^\?#]+)?(?:\?([^#]+))?(?:#(\w+))?
# 例如在js中
home = 'http://www.haofly.net/user/cp-cpi'
home.match(/该正则表达式/)
# 结果是
["http://www.haofly.net/user/cp-api", "http", undefined, undefined, "www.haofly.net", undefined, "/user/cp-api", undefined, undefined]
匹配内网地址IPv4
(^127\.)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)
匹配域名
^(?!:\/\/)([a-zA-Z0-9-_]+\.)*[a-zA-Z0-9][a-zA-Z0-9-_]+\.[a-zA-Z]{2,11}?$
^(?:[-A-Za-z0-9]+\.)+[A-Za-z]{2,6}$ # 仅仅匹配域名
匹配数字
[A-Za-z0-9]+ # 匹配整数
匹配Emali地址:
\\w+([-+.]\\w+)_@\\w+([-.]\\w+)_.\\w+([-.]\\w+)__
匹配帐号(字母开头,允许6-20字节,允许字母数字下划线)
^[a-zA-Z][a-zA-Z0-9_]\{5,19\}$
# 如果可以有中文,就写成这样
^[a-zA-Z\\u4e00-\\u9fa5][0-9a-zA-Z\\u4e00-\\u9fa5]\{1,90\}$
匹配座机和手机号码,如12341234,12345678901
\\d\{8\}|\\d\{11\}
匹配密码
^[\\@A-Za-z0-9!#\\$\\\%\\^\\&_.\\~]\{6,22\}$
匹配特殊符号(这些是建立文件夹时需要去掉的特殊符号)
\\|/|:|_|\\?|<|>|\\||.
匹配6位字符表示的颜色值,如#ffffff
^#[0-9a-fA-F]\{6\}$
非零开头正整数
^[1-9]+[0-9]*$
字符串不包含某个字符串
^((?!test).)*$ # 这里*表示匹配一次还是多次,.表示每个字符都去试一下,?!表示否定式向前查找。相当于反向每个字符都判断一下,它前面是不是那个字符串
包含且不包含
^((?!重庆).)*上海((?!重庆).)*$ # 包含上海且不包含重庆
移除HTML中的注释
/<!--[\s\S]*?-->/g
评论 · Comments
评论由 Giscus 提供,需用 GitHub 账号登录;留言会同步到这个仓库的 Discussions 里。