豪翔天下

Change My World by Program

0%

正则表达式规则及常用正则表达式

正则表达式这个东西确实有点复杂,要是每次都从头写挺麻烦的,所以就把平时会用到的都记录到这儿。

  • 在线正则表达式测试以及性能分析工具: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地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 匹配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

1
2
3
4
(^127\.)|
(^10\.)|
(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|
(^192\.168\.)

匹配域名

1
2
3
^(?!:\/\/)([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}$ # 仅仅匹配域名

匹配数字

1
[A-Za-z0-9]+   # 匹配整数

匹配Emali地址:

\\w+([-+.]\\w+)_@\\w+([-.]\\w+)_.\\w+([-.]\\w+)__

匹配帐号(字母开头,允许6-20字节,允许字母数字下划线)

1
2
3
^[a-zA-Z][a-zA-Z0-9_]\{5,19\}$
# 如果可以有中文,就写成这样
^[a-zA-Z\\u4e00-\\u9fa5][0-9a-zA-Z\\u4e00-\\u9fa5]\{1,90\}$

匹配座机和手机号码,如12341234,12345678901

1
\\d\{8\}|\\d\{11\}

匹配密码

1
^[\\@A-Za-z0-9!#\\$\\\%\\^\\&_.\\~]\{6,22\}$

匹配特殊符号(这些是建立文件夹时需要去掉的特殊符号)

1
\\|/|:|_|\\?|<|>|\\||.

匹配6位字符表示的颜色值,如#ffffff

1
^#[0-9a-fA-F]\{6\}$

非零开头正整数

1
^[1-9]+[0-9]*$

字符串不包含某个字符串

1
^((?!test).)*$	# 这里*表示匹配一次还是多次,.表示每个字符都去试一下,?!表示否定式向前查找。相当于反向每个字符都判断一下,它前面是不是那个字符串

包含且不包含

1
^((?!重庆).)*上海((?!重庆).)*$	# 包含上海且不包含重庆

移除HTML中的注释

1
/<!--[\s\S]*?-->/g

扩展阅读

坚持原创技术分享,谢谢支持

欢迎关注我的其它发布渠道