Utilo

雷杰克斯作弊表:模式,标志和现实实中的例子

一个实用的正则表达式作弊表格,包含字符类,量化器,,组,周围查看,标志和日常任务的测试模式。

· 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]。
  • 在代码中评论复杂的模式,或者从更小的字符串中构建它们。
  • 如果一个模式需要不止一两行,考虑一个小的解析器是否更清楚。

总结

学习核心类,量化器,,组和标志,。使用惰量化器和据,在需要背景时寻找周围,不要消耗它,注意嵌套量化器,并在发送模式之前始终对匹配和不匹配的示例进行测试。

本页内容由英文自动翻译而来,如发现错误,欢迎告诉我们。

相关指南