Learning Regular Expressions

regex

111591 观看

1回复

45066 作者的声誉

I don't really understand regular expressions. Can you explain them to me in an easy-to-follow manner? If there are any online tools or books, could you also link to them?

作者: Teifion 的来源 发布者: 2008 年 8 月 7 日

回应 1


753

104800 作者的声誉

The most important part is the concepts. Once you understand how the building blocks work, differences in syntax amount to little more than mild dialects. A layer on top of your regular expression engine's syntax is the syntax of the programming language you're using. Languages such as Perl remove most of this complication, but you'll have to keep in mind other considerations if you're using regular expressions in a C program.

If you think of regular expressions as building blocks that you can mix and match as you please, it helps you learn how to write and debug your own patterns but also how to understand patterns written by others.

Start simple

Conceptually, the simplest regular expressions are literal characters. The pattern N matches the character 'N'.

Regular expressions next to each other match sequences. For example, the pattern Nick matches the sequence 'N' followed by 'i' followed by 'c' followed by 'k'.

If you've ever used grep on Unix—even if only to search for ordinary looking strings—you've already been using regular expressions! (The re in grep refers to regular expressions.)

Order from the menu

添加一点复杂性,您可以将“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
  • 缺口
  • 缺口
  • Nnick
  • nNick
  • nnick
  • (等等)

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

一些其他有用的例子:

  • [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\+。反斜杠从以下字符中删除特殊含义。

贪婪

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

例如,输入是

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

你可能希望".+"只匹配'你好',然后当你看到它从'你好'到'你'时它会匹配时会感到惊讶。

要从贪婪切换到您可能认为谨慎的内容,请?为量词添加额外内容。现在您了解了\((.+?)\)问题中的示例如何工作。它匹配文字左括号的序列,后跟一个或多个字符,并以右括号结束。

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

(至于你的困惑,我不知道任何正则表达式的方言((.+?))会做同样的事情。我怀疑在路上的某处传播丢失了某些东西。)

使用特殊模式^仅在输入的开头$匹配,并且仅在结尾处匹配。用你的模式制作“书挡”,你说“我知道前后有什么,但给我一切”是一种有用的技巧。

假设您要匹配表单的注释

-- This is a comment --

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

建立你自己的

正则表达式是递归的,所以既然你已经理解了这些基本规则,你可以随意组合它们。

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

图书

免费资源

脚注

†:上述.符合任何字符的陈述是教学目的的简化,并非严格属实。Dot匹配除换行符之外的任何字符"\n",但在实践中,您很少期望一种模式,例如.+跨越换行符边界。例如,Perl正则表达式有一个/s开关和Java Pattern.DOTALL,可以.匹配任何字符。对于没有这种功能的语言,你可以使用[\s\S]匹配“任何空格或任何非空格”的东西,换句话说就是任何东西。

作者: Greg Bacon 发布者: 2010 年 5 月 3 日
32x32