雷杰克斯作弊表:模式,标志和现实实中的例子
一个实用的正则表达式作弊表格,包含字符类,量化器,,组,周围查看,标志和日常任务的测试模式。
· 6 分钟阅读
常用表达式是描述文本的紧语言。一行可以验证输入,从日志中提取数据或更名数百个文件。它们的语法很密集,。这张作弊表收集了你每天使用的语法,解释了让人们陷入困境的部分,。所有的示例都使用JavaScript语法,它也非常接近Python,Java,Go和.NET。
在阅读过程中,在regex测试 中尝试每个模式;看到突出匹配是建立直觉的最快方法。
字面上的字符和逃跑
大多数字符都匹配自己:cat匹配"猫"。十二个字符具有特殊的含义,
. * + ? ^ $ { } ( ) | [ ] \ /
所以3.14匹配"3.14",同时也匹配"3x14",而3\.14只匹配"3.14"。
字符类
| 图案 | 匹配 |
|---|---|
. |
任何字符除了新行 (除非设置了s标志) |
\d |
一个数字09 |
\w |
一个字符:字母,数字或下划线 |
\s |
白空间:空格,选项卡,新行 |
\D, \W, \S |
对于上述情况而言, |
[abc] |
一个a,b或c |
[a-z] |
任何小写的ASCII字母 |
[^0-9] |
不是数字的任何字符 |
\p{L} |
任何文字 (需要u标志) |
在方形括号内,大多数特殊字符失去了它们的意义。[.]与一个字面点相匹配。一个线条是字面上的,当放在第一个或最后一个:[-a-z]。
数量表
| 图案 | 意义 |
|---|---|
a* |
零或以上 |
a+ |
一个或多个 |
a? |
零或一个 (可选) |
a{3} |
准确的三个 |
a{2,5} |
在两到五之间 |
a{2,} |
两个或更多 |
量化器是贪的:它们尽可能地匹配,然后回溯。增加?会让他们变得惰。鉴于<b>bold</b>,模式<.+>匹配整个字符串,而<.+?>只匹配<b>。
和边界
^匹配字符串的开始,或者每个线的m标志。$匹配字符串的末尾,或者每个行与m匹配。\b匹配一个字符边界:字符和非字符之间的位置。
\bcat\b与"猫坐着"中的"猫"相匹配,。是验证必不可少的:\d{5}在"abc123456"中任何地方都会找到五个数字,而^\d{5}$则要求整个输入都必须是五个数字。
组和交替
(abc)集团和捕获。捕获的文本可用为$1,$2替换。- 没有捕获的
(?:abc)组,这更快,保持清洁的编号。 (?<year>\d{4})是一个命名的群体,可以用match.groups.year来访问。a|b与A或B相匹配。交替是最低的优先级,所以^cat|dog$意味着"从猫开始"或"从狗结束"。用^(?:cat|dog)$来匹配一个字。\1是对第1组的回顾:(\w)\1在"hello"中发现了双重字母,比如ll。
周围看看
周围观察者声称,没有消耗字符,某种东西是否与当前位置相邻。
| 图案 | 意义 |
|---|---|
(?=...) |
积极的预警:接着是 |
(?!...) |
负面的预警:没有其后的 |
(?<=...) |
积极的后视:前面是 |
(?<!...) |
负面后视:没有前面的 |
例如:\d+(?=px)匹配"16px"中的数字,没有"px";(?<=\$)\d+匹配美元符号后的数量;^(?!.*password).*$匹配没有包含"密码"的行。
旗
g(全球):找到所有匹配,而不是停留在第一个。i(忽略大小写):a匹配"A"。m(多行):^和$在线断时匹配。s(dotAll):.也符合新线。u(单码):将像表情符号这样的代码对象视为单个字符,并启用\p{...}。y(粘性):只在最后一场比赛结束的位置进行匹配。
日常任务的模式
它们是实用的,而不是详尽的。实际验证应与服务器端检查相结合。
电子邮件 (务实的):
^[^\s@]+@[^\s@]+\.[^\s@]{2,}$
捕获失踪@或域名等字体错误;唯一真正的验证是发送确认电子邮件。
标签:
^[a-z0-9]+(?:-[a-z0-9]+)*$
ISO日期 (年年至月日):
^(?<year>\d{4})-(?<month>0[1-9]|1[0-2])-(?<day>0[1-9]|[12]\d|3[01])$
这检查形状和范围,但不是是否存在2月31日;解析日期以确认。
标签:
^#(?:[0-9a-fA-F]{3}){1,2}$
IPv4地址:
^(?:(?:25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|1?\d?\d)$
语义版本:
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[\w.-]+)?(?:\+[\w.-]+)?$
强密码检查 (至少12个字符,一个小字母,一个大字母,一个数字):
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$
**切割空白:**用空字符串替换^\s+|\s+$ (以g)。
** 缩小重复的空格:** 取代 {2,}一个空格。
从日志行中提取key=value对:
(\w+)=("[^"]*"|\S+)
**camelCase到snake_case:**用$1_$2替换([a-z0-9])([A-Z]),然后小写结果。更多关于命名风格的信息,请参阅 [驼案例与蛇案例] (http://blog/naming-conventions-camelcase-snake-case)。
性能和灾难性追溯
在JavaScript,Python和Java中使用的Regex引擎使用了回溯。一些模式迫使发动机在几乎匹配的输入中尝试指数式数量的组合。典型的例子是^(a+)+$对阵"aaaaaaaaaaaaaaaaaaaa!"。每个额外的"a"都会使工作翻倍,
为了避免这种情况:
- 不要将量化符嵌入相同的字符上,例如
(a+)+或(\w*)*。 - 让替代方案相互排斥:
(a|ab)*是有风险的;重组它。 - 偏好特定类别而不是
.*:"[^"]*"比".*?"更安全,更快。 - 在匹配不可靠数据之前限制输入长度。
可读性提示
- 逐步构建复杂的图案,并测试每一块。
- 使用命名组,以便代码读取
m.groups.month而不是m[2]。 - 在代码中评论复杂的模式,或者从更小的字符串中构建它们。
- 如果一个模式需要不止一两行,考虑一个小的解析器是否更清楚。
总结
学习核心类,量化器,,组和标志,。使用惰量化器和据,在需要背景时寻找周围,不要消耗它,注意嵌套量化器,并在发送模式之前始终对匹配和不匹配的示例进行测试。
本页内容由英文自动翻译而来,如发现错误,欢迎告诉我们。