问题

我真的不明白正则表达式.你能用一种容易理解的方式向我解释一下吗?如果有任何在线工具或书籍,您还可以链接到他们吗?



解决方法

最重要的部分是概念.一旦你理解了构建块的工作原理,语法的差异只是轻微的方言.正则表达式引擎语法之上的一个层是您使用的编程语言的语法. Perl等语言可以消除大部分复杂情况,但如果您在C程序中使用正则表达式,则必须记住其他注意事项.

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

Start simple

在概念上,最简单的正则表达式是字面字符.模式 N 匹配字符"N".

彼此相邻的正则表达式匹配序列.例如,模式 Nick 匹配序列'N'后跟'i',后跟'c',后跟'k'.

如果你曾在Unix上使用过 grep ,即使只是为了搜索普通的字符串,你已经使用了正则表达式! ( re grep 是指正则表达式.)

Order from the menu

添加一点点复杂性,你可以匹配'Nick'或'nick'与模式 [Nn] ick .方括号中的部分是一个字符类,这意味着它只匹配一个包含的字符.您还可以在字符类中使用范围,因此 [a-c] 匹配'a'或'b'或'c'.

模式.是特殊的:不是仅匹配文字点,而是匹配任何字符.它与真正的大字符类 [-.?+%$ A-Za-z0-9 ...] 在概念上是一样的.

将字符类视为菜单:只选择一个.

Helpful shortcuts

Using . can save you lots of typing, and there are other shortcuts for common patterns. Say you want to match non-negative integers: one way to write that is [0-9]+. Digits are a frequent match target, so you could instead use \d+ match non-negative integers. Others are \s (whitespace) and \w (word characters: alphanumerics or underscore).

The uppercased variants are their complements, so \S matches any non-whitespace character, for example.

Once is not enough

在这里,您可以使用量词重复部分模式.例如,模式 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
  • Nick
  • nick
  • Nnick
  • nNick
  • nnick
  • (and so on)

第一个匹配展示了一个重要的教训: * 始终成功!任何模式都可以匹配零次.

Grouping

量词将模式修改为其左侧.您可能希望 0abc + 0 匹配'0abc0','0abcabc0',等等,但是加号量化符左边的 .这意味着 0abc + 0 匹配'0abc0','0abcc0','0abccc0'等.

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

Alternation

以前,我们看到了一种匹配"Nick"或"nick"的方法.另一个是交替,如 Nick | nick .记住,交替包括其左边的一切,右边的一切.使用分组括号限制 | ,例如,(Nick | nick)

对于另一个例子,您可以等效地将 [ac] 写为 a | b | c ,但这可能不是最佳的,因为许多实现假设替代品将具有长度大于1.

Escaping

Although some characters match themselves, others have special meanings. The pattern \d+ doesn't match backslash followed by lowercase D followed by a plus sign: to get that, we'd use \\d\+. A backslash removes the special meaning from the following character.

Greediness

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

例如,假设输入是

"Hello," she said, "How are you?"

您可能希望".+"只匹配"Hello",然后当您看到它从"Hello"一直到"you? p>

To switch from greedy to what you might think of as cautious, add an extra ? to the quantifier. Now you understand how \((.+?)\), the example from your question works. It matches the sequence of a literal left-parenthesis, followed by one or more characters, and terminated by a right-parenthesis.

如果您的输入为"(123)(456)",则第一个捕获将为"123".非贪心量词想要允许模式的其余部分尽快开始匹配.

(至于你的混淆,我不知道任何正则表达式方言,((.+?))会做同样的事情.方式.)

Anchors

使用特殊模式 ^ 仅在输入开头匹配, $ 仅匹配结尾.用你的模式制作"书",你说"我知道前面和后面的东西,但是给我之间的东西"是一种有用的技术.

假设您要匹配表单

的评论

-- This is a comment --

you'd write ^--\s+(.+)\s+--$.

Build your own

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

Tools for writing and debugging regexes:

Books

Free resources

Footnote

†: 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.




相关问题推荐