我真的不明白正则表达式。你能以易于理解的方式向我解释吗?如果有任何在线工具或书籍,您能否也链接到它们?
1 回答
最重要的部分是概念。一旦您了解了构建块的工作原理,语法上的差异只不过是温和的方言而已。正则表达式引擎语法之上的一层是您正在使用的编程语言的语法。诸如 Perl 之类的语言消除了大部分这种复杂性,但如果您在 C 程序中使用正则表达式,则必须牢记其他注意事项。
如果您将正则表达式视为可以随意混合和匹配的构建块,它可以帮助您学习如何编写和调试自己的模式,以及如何理解其他人编写的模式。
开始简单
从概念上讲,最简单的正则表达式是文字字符。该模式N
与字符“N”匹配。
彼此相邻的正则表达式匹配序列。例如,该模式Nick
匹配序列“N”后跟“i”后跟“c”后跟“k”。
如果你曾经grep
在 Unix 上使用过——即使只是为了搜索普通字符串——你已经在使用正则表达式了!(re
ingrep
指的是正则表达式。)
从菜单中订购
只需增加一点复杂性,您就可以将 'Nick' 或 'nick' 与 pattern 匹配[Nn]ick
。方括号中的部分是一个字符类,这意味着它与一个封闭的字符完全匹配。您还可以在字符类中使用范围,因此[a-c]
匹配“a”或“b”或“c”。
该模式.
很特殊:它不仅匹配文字点,还匹配任何字符†</sup>。它在概念上与真正的大字符类相同[-.?+%$A-Za-z0-9...]
。
将字符类视为菜单:只选择一个。
有用的快捷方式
使用.
可以为您节省大量输入,并且还有其他常用模式的快捷方式。假设你想匹配一个数字:一种写法是[0-9]
. 数字是一个常见的匹配目标,因此您可以改用快捷方式\d
。其他是\s
(空白)和\w
(单词字符:字母数字或下划线)。
大写的变体是它们的补码,因此\S
匹配任何非空白字符,例如。
一次是不够的
从那里,您可以使用quantifiers重复部分模式。例如,模式ab?c
匹配“abc”或“ac”,因为?
量词使其修改的子模式成为可选。其他量词是
*
(零次或多次)+
(一次或多次){n}
(正好n次){n,}
(至少n次){n,m}
(至少n次但不超过m次)
将其中一些块放在一起,模式[Nn]*ick
匹配所有
- ick
- 缺口
- 缺口
- 尼克
- 尼克
- 尼克
- (等等)
第一场比赛展示了一个重要的教训:*
总是成功!任何模式都可以匹配零次。
其他一些有用的例子:
[0-9]+
(及其等价物\d+
)匹配任何非负整数\d{4}-\d{2}-\d{2}
匹配格式为 2019-01-01 的日期
分组
量词将模式修改到其紧邻的左侧。您可能希望0abc+0
匹配 '0abc0'、'0abcabc0' 等,但紧靠加号量词左侧的模式是c
. 这意味着0abc+0
匹配“0abc0”、“0abcc0”、“0abccc0”等。
要匹配一个或多个末端为零的“abc”序列,请使用0(abc)+0
. 括号表示可以量化为一个单元的子模式。正则表达式引擎保存或“捕获”与括号组匹配的输入文本部分也很常见。以这种方式提取位比计算索引和substr
.
交替
早些时候,我们看到了一种匹配“Nick”或“nick”的方法。另一种是交替,如Nick|nick
。请记住,交替包括左侧的所有内容和右侧的所有内容。使用分组括号来限制的范围|
,例如.(Nick|nick)
再举一个例子,您可以等效地写[a-c]
为a|b|c
,但这可能不是最理想的,因为许多实现都假设替代方案的长度大于 1。
逃跑
虽然有些字符匹配自己,但其他字符具有特殊含义。该模式\d+
不匹配反斜杠后跟小写 D 后跟加号:要得到它,我们将使用\\d\+
. 反斜杠从后面的字符中删除特殊含义。
贪婪
正则表达式量词是贪婪的。这意味着它们匹配尽可能多的文本,同时允许整个模式成功匹配。
例如,假设输入是
“你好,”她说,“你好吗?”
您可能希望".+"
只匹配“Hello”,然后当您看到它从“Hello”一直匹配到“you?”时会感到惊讶。
要从贪婪切换到您可能认为的谨慎,?
请在量词中添加额外的内容。现在您了解了\((.+?)\)
问题中的示例是如何工作的。它匹配文字左括号的序列,后跟一个或多个字符,并以右括号终止。
如果您的输入是“(123)(456)”,那么第一个捕获将是“123”。非贪婪量词希望让模式的其余部分尽快开始匹配。
(至于您的困惑,我不知道任何正则表达式方言((.+?))
会在哪里做同样的事情。我怀疑在传输过程中某处丢失了某些东西。)
锚点
使用特殊模式^
仅在输入的开头$
匹配并仅在结尾匹配。用你的模式制作“书挡”,你说,“我知道前面和后面是什么,但把中间的一切都给我”是一种有用的技术。
假设您要匹配表单的注释
-- This is a comment --
你会写^--\s+(.+)\s+--$
。
建立你自己的
正则表达式是递归的,所以现在您了解了这些基本规则,您可以随意组合它们。
编写和调试正则表达式的工具:
- 正则表达式(用于 JavaScript)
- Perl:YAPE:正则表达式解释
- Regex Coach(由CL-PPCRE支持的引擎)
- 正则表达式(用于 JavaScript)
- 正则表达式在线测试器
- 正则表达式好友
- 正则表达式 101(用于 PCRE、JavaScript、Python、Golang、Java 8)
- 我讨厌正则表达式
- 视觉正则表达式
- Expresso(用于 .NET)
- Rubular(用于 Ruby)
- 正则表达式库(常见场景的预定义正则表达式)
- 文本2RE
- 正则表达式测试器(用于 JavaScript)
- 正则表达式风暴(用于 .NET)
- Debuggex(可视化正则表达式测试器和助手)
图书
免费资源
脚注
†:以上匹配任何字符的陈述.
是出于教学目的的简化,并非严格正确。点匹配除换行符之外的任何字符"\n"
,但实际上您很少期望诸如.+
跨越换行符边界的模式。Perl 正则表达式有一个/s
switch和 Java Pattern.DOTALL
,例如,可以.
匹配任何字符。对于不具有此类功能的语言,您可以使用诸如[\s\S]
匹配“任何空白或任何非空白”之类的东西,换句话说就是任何东西。