学习正则表达式
我不太了解正则表达式。我们能以一种易于理解的方式向我解释它们吗?如果有任何在线工具或者书籍,我们还可以链接到它们吗?
解决方案
回答
最重要的部分是概念。一旦了解了构建块的工作原理,语法上的差异就等于轻度方言。正则表达式引擎语法之上的一层是我们正在使用的编程语言的语法。诸如Perl之类的语言消除了大多数这种复杂性,但是如果我们在C程序中使用正则表达式,则必须牢记其他注意事项。
如果我们将正则表达式视为可以随意混合和匹配的构建基块,那么它可以学习如何编写和调试自己的模式,以及如何理解他人编写的模式。
从简单开始
从概念上讲,最简单的正则表达式是文字字符。模式" N"与字符" N"匹配。
彼此相邻的正则表达式匹配序列。例如,模式" Nick"与序列" N"," i"," c"," k"匹配。
如果我们曾经在Unix上使用过grep,即使只是为了搜索普通的字符串,我们就已经在使用正则表达式! (" grep"中的" re"是指正则表达式。)
从菜单订购
稍微增加一点复杂性,我们就可以将'Nick'或者'nick'与模式[Nn] ick相匹配。方括号中的部分是一个字符类,这意味着它与所包含的字符之一完全匹配。我们还可以在字符类中使用范围,因此[a-c]
可以匹配'a'或者'b'或者'c'。
模式.
是特殊的:它不仅匹配文字点,还匹配任何字符?。它在概念上与真正的大字符类[-.?+%$ A-Za-z0-9 ...]
相同。
将角色类视为菜单:仅选择一个。
有用的快捷方式
使用`。'可以节省大量的键入时间,并且还有一些其他常用模式的快捷方式。假设我们要匹配非负整数:一种写方法是[0-9] +。数字是经常匹配的目标,因此我们可以改用\ d +来匹配非负整数。其他的是" \ s"(空格)和" \ w"(单词字符:字母数字或者下划线)。
大写字母的变体是它们的补语,因此,例如,\ S匹配任何非空白字符。
一次还不够
从那里,我们可以使用量词重复模式的某些部分。例如,模式" ab?c"与" abc"或者" ac"匹配,因为"?"量词使它修改的子模式为可选。其他量词是
- *(零次或者多次)
+
(一次或者多次)- " {n}"(恰好n次)
{n,}
(至少n次){n,m}
(至少n次,但不超过m次)
将其中一些块放在一起,模式[[Nn] * ick`匹配所有
- ick
- 缺口
- 缺口
- 尼克
- 尼克
- 尼克
- (等等)
第一场比赛展示了一个重要的教训:`*总是成功!任何模式都可以匹配零次。
分组
量词将模式修改到其紧邻的左侧。我们可能希望0abc + 0
匹配'0abc0','0abcabc0'等,但是加号修饰符左侧的模式是`c'。这意味着" 0abc + 0"匹配" 0abc0"," 0abcc0"," 0abccc0",依此类推。
要匹配一个或者多个'abc'序列的末端为零,请使用'0(abc)+0'。括号表示可以量化为一个单位的子模式。正则表达式引擎通常会保存或者"捕获"与括号组匹配的输入文本部分。与对索引和`substr'进行计数相比,以这种方式提取位更加灵活并且不易出错。
轮换
之前,我们看到了一种匹配"尼克"或者"尼克"的方法。另一个与" Nick | nick"中的交替。请记住,交替包括其左侧的所有内容和右侧的所有内容。使用分组括号来限制|
的范围,例如(Nick | nick)
。
再举一个例子,我们可以将[[a-c]等效地写为
a | b | c`,但这可能不是最优的,因为许多实现都假定替代方法的长度大于1.
转义
尽管某些字符匹配,但其他字符具有特殊含义。模式'\ d +'与反斜杠,小写字母D和加号不匹配:要实现此目的,我们将使用\\ d \ +
。反斜杠从后面的字符中删除特殊含义。
贪婪
正则表达式量词是贪婪的。这意味着它们可以匹配尽可能多的文本,同时允许整个模式成功匹配。
例如,假设输入为
"Hello," she said, "How are you?"
我们可能会期望"。+"仅匹配" Hello",然后当我们看到它与" Hello"一直匹配到" you?"时,我们会感到惊讶。
要从贪婪转向谨慎,可以在量词上添加一个额外的"?"。现在,我们了解了问题中的示例" ((。+?))"的工作方式。它与文字左括号的顺序匹配,后接一个或者多个字符,并以右括号终止。
如果我们输入的是'(123)(456)',则第一个捕获将是'123'。非贪婪的量词希望允许模式的其余部分尽快开始匹配。
(关于困惑,我不知道在([..?
锚点
使用特殊模式^
仅在输入的开头进行匹配,$
仅在输入的末尾进行匹配。用模式制作"书挡",我们说:"我知道正面和背面是什么,但是请给我之间的一切"是一种有用的技术。
假设我们要匹配表单的注释
-- This is a comment --
我们会写成^-\ s +(。+)\ s +-$
。
建立你自己的
正则表达式是递归的,因此,既然我们了解了这些基本规则,就可以随意组合它们。
编写和调试正则表达式的工具:
- RegExr(用于JavaScript)
- Perl:YAPE:Regex解释
- 正则表达式教练(由CL-PPCRE支持的引擎)
- RegexPal(适用于JavaScript)
- 正则表达式在线测试器
- 正则表达式好友
- 正则表达式101(用于PCRE,JavaScript,Python,Golang)
- 视觉正则表达式
- Expresso(用于.NET)
- Rubular(对于Ruby)
- 正则表达式库(常见方案的预定义正则表达式)
- Txt2RE
- 正则表达式测试器(用于JavaScript)
- 正则表达式风暴(.NET)
- Debuggex(可视化正则表达式测试器和帮助器)
图书
- 掌握正则表达式,第二版和第三版。
- 正则表达式备忘单
- 正则表达式食谱
- 教自己正则表达式
免费资源
- 正则表达式-我们应该知道的一切(PDF系列)
- 正则表达式语法摘要
- 正则表达式如何工作
脚注
?:上面的.
与任何字符匹配的陈述是出于教学目的的简化,并非严格如此。点匹配除换行符" \ n"之外的任何字符,但是在实践中,我们很少期望像..这样的字符跨越换行符边界。 Perl正则表达式具有一个" / s"开关和例如Java" Pattern.DOTALL",以使"。"与任何字符完全匹配。对于没有这种功能的语言,可以使用诸如[[\ s \ S]`之类的东西来匹配"任何空白或者任何非空白",换句话说,就是任何东西。