学习正则表达式

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

0

1 答案

最重要的部分是概念。一旦你了解积木是如何工作的,语法上的差异只不过是轻微的方言。正则表达式引擎语法顶部的图层是您正在使用的编程语言的语法。像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',因为量词使得它修改的子模式成为可选。其他量词是

  • * (zero or more times)
  • + (one or more times)
  • {n} (exactly n times)
  • {n,} (at least n times)
  • {n,m} (at least n times but no more than m times)

将这些块中的一部分放在一起,模式 [Nn] * ick 匹配全部

  • ICK
  • 尼克
  • 缺口
  • Nnick
  • nNick
  • nnick
  • (等等)

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

分组

量词将模式修改为其左侧。您可能希望 0abc + 0 与'0abc0','0abcabc0'等匹配,但加号量词左侧的模式c </代码>。这意味着 0abc + 0 匹配'0abc0','0abcc0','0abccc0'等等。

要将一个或多个'abc'序列与末尾的零匹配,请使用 0(abc)+0 。括号表示可以量化为一个单元的子模式。正则表达式引擎保存或“捕获”与加括号的组匹配的输入文本部分也很常见。以这种方式提取位比计数索引和 substr 更灵活,更不容易出错。

轮流

Earlier, we saw one way to match either 'Nick' or 'nick'. Another is with 轮流 as in Nick|nick. Remember that 轮流 includes everything to its left and everything to its right. Use 分组 parentheses to limit the scope of |, e.g., (Nick|nick).

再举一个例子,您可以等价地将 [ac] 写成 a | b | c ,但这可能不是最理想的,因为许多实现假定备选将具有大于1的长度。

逃离

虽然有些角色自己匹配,但其他角色具有特殊的含义。模式 \ d + 不匹配反斜杠,接着是小写字母D,后跟一个加号:为了得到这个结果,我们使用 \\ d \ + 。反斜杠从以下字符中删除特殊含义。

贪婪

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

例如,说输入是

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

您可能希望“。+”仅匹配'Hello',然后当您看到它从'Hello'一路匹配'you?'时会感到惊讶。

要从贪婪切换到您可能认为谨慎的地方,请向量词添加额外的。现在你已经理解 \((。+?)\)是如何工作的。它与字面左括号的序列相匹配,后跟一个或多个字符,并以右括号结束。

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

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

使用特殊模式 ^ 仅在输入开始时匹配,而 $ 仅在末尾匹配。用你所说的模式制作“书挡”,“我知道正面和背面有什么,但给我之间的一切”是一种有用的技巧。

假设你想匹配表单的评论

- 这是一条评论 -

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

建立你自己的

正则表达式是递归的,所以现在你已经理解了这些基本规则,不管你喜欢什么,你都可以将它们组合起来。

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

图书

免费资源

脚注

?: The statement above that . matches any character is a simplification for pedagogical purposes that is not strictly true. Dot matches any character except newline, "\n", but in practice you rarely expect a pattern such as .+ to cross a newline boundary. Perl regexes have a /s switch and Java Pattern.DOTALL, for example, to make . match any character at all. For languages that don't have such a feature, you can use something like [\s\S] to match "any whitespace or any non-whitespace", in other words anything.

0
额外
您也可以使用试验和错误的方法,而不是以下在线正则表达式测试器和调试器可以是一个巨大的帮助: regex101.com
额外 作者 Juraj.Lorinc,
值得一提的是,有不同类型的正则表达式引擎,它们都具有不同的特征集和语法规则。
额外 作者 hek2mgl,
值得一提的是,尽管是相似的模式,但至少在Javascript,Perl和Python中, a {,m} 并不是什么东西。
额外 作者 Nic Hartley,
hackr.io/tutorials/learn-regular-expressions-regex 是一个伟大的找到最好的在线正则表达式教程。这里的所有教程都是由编程社区提交和推荐的(比如SO)。
额外 作者 Saurabh Hooda,