学习正则表达式


166

我不太了解正则表达式。您能以简单易懂的方式向我解释吗?如果有任何在线工具或书籍,您还可以链接到它们吗?

Answers:


789

最重要的部分是概念。一旦您了解了构建块的工作原理,语法上的差异就等于温和的方言。正则表达式引擎语法之上的一层是您正在使用的编程语言的语法。诸如Perl之类的语言消除了大多数这种复杂性,但是如果您在C程序中使用正则表达式,则必须牢记其他注意事项。

如果您将正则表达式视为可以随意混合和匹配的构建基块,那么它可以帮助您学习如何编写和调试自己的模式,以及如何理解他人编写的模式。

从简单开始

从概念上讲,最简单的正则表达式是文字字符。该模式N与字符“ N”匹配。

正则表达式彼此相邻,匹配序列。例如,模式Nick与序列“ N”,“ i”,“ c”,“ k”匹配。

如果您曾经grep在Unix上使用过-即使仅用于搜索普通的字符串-您也已经在使用正则表达式!(rein grep表示正则表达式。)

从菜单订购

稍微增加一点复杂性,您就可以将'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
  • 缺口
  • 缺口
  • 尼克
  • 尼克
  • 尼克
  • (等等)

第一场比赛展示了一个重要的教训:*永远成功!任何模式都可以匹配零次。

其他一些有用的例子:

  • [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)

另一个例子,你能等效写[a-c]a|b|c,但这很可能是次优的,因为许多实现假定方案将有长度大于1。

转义

尽管某些字符匹配,但其他字符具有特殊含义。该模式\d+与反斜杠,小写字母D和加号不匹配:要使用该格式,请使用\\d\+。反斜杠从后面的字符中删除特殊含义。

贪婪

正则表达式量词是贪婪的。这意味着它们可以匹配尽可能多的文本,同时允许整个模式成功匹配。

例如,假设输入为

“你好,”她说,“你好吗?”

您可能会期望 ".+"只匹配“ Hello”,然后看到它从“ Hello”一直到“ you?”一直匹配,然后会感到惊讶。

要从贪婪转向谨慎,?可以在量词上添加一个额外的内容。现在您了解了\((.+?)\)问题的示例的工作原理。它与文字左括号的顺序匹配,后接一个或多个字符,并以右括号终止。

如果您输入的是'(123)(456)',则第一个捕获将是'123'。非贪婪的量词希望允许模式的其余部分尽快开始匹配。

(关于您的困惑,我不知道任何正则表达式的方言会在哪里((.+?))做同样的事情。我怀疑在传输过程中某些地方丢失了某些东西。)

锚点

使用特殊模式^仅在输入的开头$进行匹配,而仅在输入的末尾进行匹配。用您的模式制作“书挡”,您说:“我知道正面和背面是什么,但请给我之间的一切”是一种有用的技术。

假设您要匹配表单的注释

-- This is a comment --

你会写^--\s+(.+)\s+--$

建立你自己的

正则表达式是递归的,因此既然您了解了这些基本规则,就可以随意组合它们。

编写和调试正则表达式的工具:

图书

免费资源

脚注

†:上面的语句.与任何字符匹配都是出于教学目的的简化,并非严格如此。点与除换行符()外的任何字符都匹配"\n",但是在实践中,您很少会期望出现.+跨越换行符边界的模式。Perl正则表达式具有一个/sswitch和Java Pattern.DOTALL,例如,可以使.所有字符完全匹配。对于没有这种功能的语言,您可以使用类似[\s\S]“任何空白或任何非空白”的匹配方式,换句话说,就是任何东西。


14
您还可以使用反复试验的方法,比下面的在线regex测试器和调试器大有
Juraj.Lorinc

2
值得一提的是,尽管是类似的模式,但a{,m}至少在Javascript,Perl和Python中,这不是问题。
基金莫妮卡的诉讼案

2
值得一提的是,有不同种类的正则表达式引擎,它们都有不同的功能集和语法规则。
hek2mgl

1
hackr.io/tutorials/learn-regular-expressions-regex是查找最佳在线regex教程的好地方。此处的所有教程均由编程社区提交和推荐(如SO一样推荐)。
Saurabh Hooda

2
概括地说,感谢您为将其全部应用到此处而付出的努力。
萨拉·蒂瓦里
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.