提问人: 提问时间:8/7/2008 最后编辑:5 revs, 4 users 67%Teifion 更新时间:11/11/2022 访问量:152616
学习正则表达式 [已关闭]
Learning Regular Expressions [closed]
问:
我真的不懂正则表达式。你能用一种通俗易懂的方式向我解释一下吗?如果有任何在线工具或书籍,您还能链接到它们吗?
答:
最重要的部分是概念。一旦你了解了构建块的工作原理,语法上的差异就只不过是温和的方言而已。正则表达式引擎语法之上的一层是你正在使用的编程语言的语法。像 Perl 这样的语言消除了大部分的复杂性,但如果在 C 程序中使用正则表达式,则必须牢记其他注意事项。
如果您将正则表达式视为可以随意混合和匹配的构建块,那么它可以帮助您学习如何编写和调试自己的模式,以及如何理解其他人编写的模式。
从简单开始
从概念上讲,最简单的正则表达式是文字字符。该模式与字符“N”匹配。N
彼此相邻的正则表达式匹配序列。例如,该模式匹配序列“N”,后跟“i”,后跟“c”,后跟“k”。Nick
如果你曾经在 Unix 上使用过——即使只是为了搜索看起来很普通的字符串——你已经使用过正则表达式了!(in 是指正则表达式。grep
re
grep
从菜单中订购
只需增加一点复杂性,您就可以将“Nick”或“nick”与模式匹配。方括号中的部分是字符类,这意味着它正好匹配一个括起来的字符。您还可以在字符类中使用范围,以便匹配“a”或“b”或“c”。[Nn]ick
[a-c]
该模式很特别:它不是只匹配文字点,而是匹配任何字符†。这在概念上与真正的大字符类相同。.
[-.?+%$A-Za-z0-9...]
将角色类视为菜单:只选择一个。
有用的快捷方式
使用可以为您节省大量键入时间,并且对于常见模式还有其他快捷方式。假设您要匹配一个数字:一种写法是 .数字是常见的匹配目标,因此您可以改用快捷方式。其他是(空格)和(单词字符:字母数字或下划线)。.
[0-9]
\d
\s
\w
例如,大写变体是它们的补码,因此可以匹配任何非空格字符。\S
一次是不够的
从那里,您可以使用量词重复模式的某些部分。例如,模式匹配“abc”或“ac”,因为量词将其修改的子模式设置为可选。其他量词是ab?c
?
*
(零次或多次)+
(一次或多次){n}
(正好n次){n,}
(至少 n 次){n,m}
(至少 n 次但不超过 m 次)
将其中一些块放在一起,该模式将所有[Nn]*ick
- ick
- 缺口
- 缺口
- 尼克
- n尼克
- 尼克
- (依此类推)
第一场比赛展示了一个重要的教训:*
总是成功的!任何模式都可以匹配零次。
其他一些有用的例子:
[0-9]+
(及其等价物)匹配任何非负整数\d+
\d{4}-\d{2}-\d{2}
匹配格式为 2019-01-01 的日期
分组
量词将模式修改到其紧靠的左侧。您可能希望匹配 '0abc0'、'0abcabc0' 等,但紧挨着加号量词左侧的模式是 。这意味着匹配 '0abc0'、'0abcc0'、'0abccc0' 等。0abc+0
c
0abc+0
要匹配一个或多个两端为零的“abc”序列,请使用 .括号表示可以量化为一个单元的子模式。正则表达式引擎保存或“捕获”与括号组匹配的输入文本部分也很常见。以这种方式提取位比计算索引和 更灵活,更不容易出错。0(abc)+0
substr
交替
早些时候,我们看到了一种匹配“Nick”或“nick”的方法。另一个是交替,如 .请记住,交替包括左边的一切和右边的一切。使用分组括号来限制 的范围,例如 .Nick|nick
|
(Nick|nick)
再举一个例子,您可以等效地写成 ,但这可能是次优的,因为许多实现都假定备选项的长度大于 1。[a-c]
a|b|c
逃避
虽然有些字符与自己匹配,但其他字符具有特殊含义。该模式与后跟小写字母 D 后跟加号的反斜杠不匹配:为此,我们将使用 .反斜杠会删除以下字符的特殊含义。\d+
\\d\+
贪欲
正则表达式量词是贪婪的。这意味着它们可以匹配尽可能多的文本,同时允许整个模式成功匹配。
例如,假设输入是
“你好,”她说,“你好吗?
您可能希望只匹配“Hello”,然后当您看到它从“Hello”一直匹配到“you?”时,您会感到惊讶。".+"
要从贪婪切换到您可能认为的谨慎,请在量词中添加一个额外的内容。现在您了解了问题中的示例是如何工作的。它与文字左括号的顺序匹配,后跟一个或多个字符,并以右括号结束。?
\((.+?)\)
如果您的输入是“(123) (456)”,则第一个捕获将是“123”。非贪婪量词希望允许模式的其余部分尽快开始匹配。
(至于你的困惑,我不知道任何正则表达式方言会做同样的事情。我怀疑在途中某处的传输中丢失了一些东西。((.+?))
锚
使用特殊模式仅在输入的开头匹配,仅在输入的末尾匹配。用你的模式制作“书挡”,你说,“我知道前面和后面是什么,但给我中间的一切”是一种有用的技巧。^
$
说您要匹配表单的注释
-- This is a comment --
你会写.^--\s+(.+)\s+--$
构建自己的
正则表达式是递归的,所以现在你已经了解了这些基本规则,你可以随心所欲地组合它们。
用于编写和调试正则表达式的工具:
- RegExr(适用于 JavaScript)
- Perl:YAPE:正则表达式解释
- 正则表达式 Coach(由 CL-PPCRE 支持的引擎)
- RegexPal(适用于 JavaScript)
- 正则表达式在线测试器
- 正则表达式好友
- 正则表达式 101(适用于 PCRE、JavaScript、Python、Golang、Java 8)
- 我讨厌正则表达式
- 可视正则表达式
- Expresso(适用于 .NET)
- Rubular(用于 Ruby)
- 正则表达式库(常见方案的预定义正则表达式)
- Txt2RE的
- 正则表达式测试器(适用于 JavaScript)
- 正则表达式风暴(适用于 .NET)
- Debuggex(可视正则表达式测试器和帮助程序)
书
免费资源
脚注
†:上面与任何字符匹配的陈述是出于教学目的的简化,并不完全正确。Dot 匹配除换行符以外的任何字符,但在实践中,您很少期望出现跨越换行符边界之类的模式。例如,Perl 正则表达式有一个 /s
开关和 Java Pattern.DOTALL,
可以匹配任何字符。对于没有这种功能的语言,你可以使用类似的东西来匹配“任何空格或任何非空格”,换句话说,任何空格。.
"\n"
.+
.
[\s\S]
评论
a{,m}
评论