RegEx:掌握正则表达式的 20 个简短步骤。第 1 部分 原文在这里 在上一部分中我们掌握了最简单的正则表达式,并且已经学到了一些东西。在这一部分中,我们将研究稍微复杂的设计,但相信我,它不会像看起来那么困难。 那么让我们继续吧!
第 8 步:星号
到目前为止,我们或多或少只能匹配给定长度的字符串。但在最近的问题中,我们已经接近了迄今为止我们所看到的符号的极限。例如,假设我们不限于 3 字符 Java 标识符,而是可以具有任意长度的标识符。在上一个示例中可能有效的解决方案在以下示例中将不起作用:
第9步:“可选”问号
您已经编写了正则表达式来解决最后一个问题吗?有效吗?现在尝试在这里应用它:
第10步:“或”号
在第 8 步中,我们在查找不同类型的浮点数时遇到了一些困难:
第 8 步:星号*
和加号+
到目前为止,我们或多或少只能匹配给定长度的字符串。但在最近的问题中,我们已经接近了迄今为止我们所看到的符号的极限。例如,假设我们不限于 3 字符 Java 标识符,而是可以具有任意长度的标识符。在上一个示例中可能有效的解决方案在以下示例中将不起作用:
模式:[a-zA-Z_$]\w\w 字符串: __e $12 3 3.2 fo Bar r a23 mm ab x 匹配:^^^ ^^^ ^^^ ^^^(例子) 笔记当标识符有效但长度超过 3 个字符时,仅匹配前三个字符。当标识符有效,但包含少于 3 个字符时,正则表达式根本找不到它!问题是括号表达式与
[]
一个字符完全匹配,就像\w
. 这意味着上述正则表达式中的任何匹配项都必须恰好是三个字符长。所以它的效果并没有我们希望的那么好。*
特殊字符和可以在这里提供帮助+
。这些修饰符可以添加到任何表达式的右侧,以多次匹配该表达式。Kleene Star(或“星号”)*
将指示前一个标记必须匹配任意次数,包括零次。加号+
表示您需要搜索一次或多次。因此,前面的表达式+
是强制性的(至少一次),而前面的表达式*
是可选的,但当它出现时,它可以出现任意多次。现在,有了这些知识,我们可以纠正上面的正则表达式:
模式:[a-zA-Z_$]\w* 字符串: __e $123 3.2 fo Barr a23mm ab x 匹配:^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^(示例)现在我们匹配任意长度的有效标识符!答对了!
+
但是如果我们使用 ?而不是?会发生什么*
?
模式:[a-zA-Z_$]\w+ 字符串: __e $123 3.2 fo Barr a23mm ab x 匹配:^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^(示例)我们错过了最后一场比赛,
х
。这是因为它需要+
至少匹配一个字符,但是由于[]
前面的括号表达式\w+
已经“吃掉”了该字符x
,所以没有更多的可用字符,因此匹配失败。我们什么时候可以使用+
?当我们需要找到至少一个匹配项,但给定表达式必须匹配多少次并不重要。例如,如果我们想查找任何包含小数点的数字:
模式:\d*\.\d+ 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 匹配:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^(例子) 笔记通过将小数点左边的数字设为可选,我们能够找到 0.011 和 0.2。为此,我们需要将一位小数点与 精确匹配
\.
,并将小数点右侧至少一位数字与 匹配\d+
。上面的正则表达式不会匹配像这样的数字3.
,因为我们需要小数点右边至少一位数字才能匹配。
像往常一样,让我们解决几个简单的问题:
找出下面段落中的所有英语单词。图案: 字符串:3加3是 6,但4加 3 是7 匹配: ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^(解决方案)在下面的列表中找到所有文件大小符号。文件大小将由一个数字(带或不带小数点)后跟
KB
、MB
或组成: GB
TB
图案: 字符串: 11TB 13 14.4MB 22HB 9.9GB TB 0KB 匹配:^^^^ ^^^^^^ ^^^^^ ^^^(解决方案)
第9步:“可选”问号?
您已经编写了正则表达式来解决最后一个问题吗?有效吗?现在尝试在这里应用它:
图案: 字符串:1..3KB 5...GB ..6TB 火柴:显然,这些指定都不是有效的文件大小,因此好的正则表达式不应与它们中的任何一个匹配。我为解决最后一个问题而编写的解决方案与它们全部匹配,至少部分匹配:
模式:\d+\.*\d*[KMGT]B 字符串: 1..3KB 5...GB .. 6TB 匹配:^^^^^^ ^^^^^^ ^^^(示例)那么问题出在哪里呢?事实上,如果有一位小数点的话,我们只需要找到一位小数点即可。但
*
它允许任意数量的匹配,包括零。有没有办法只匹配零次或一次?但不超过一次吗?当然有。“可选”?
是一个修饰符,匹配零个或一个前面的字符,但不能再匹配:
模式:\d+\.?\d*[KMGT]B 字符串:1.. 3KB 5...GB .. 6TB 匹配: ^^^ ^^^(示例)我们在这里更接近解决方案,但这并不是我们所需要的。稍后我们将通过几个步骤了解如何解决此问题。
同时,让我们解决这个问题:
在某些编程语言(例如 Java)中,某些整数和浮点(点)数字可能会后跟l
/L
和f
/F
来指示它们应该(分别)被视为 long/float,而不是常规的 int/double。在下面的行中找到所有有效的“长”数字:
图案: 字符串: 13L long 2l 19 L lL 0 匹配:^^^ ^^ ^^ ^(解决方案)
第10步:“或”号|
在第 8 步中,我们在查找不同类型的浮点数时遇到了一些困难:
模式:\d*\.\d+ 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 匹配:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^上面的模式匹配带有小数点且小数点右侧至少一位数字的数字。但是如果我们还想匹配像这样的字符串怎么办
0.
?(小数点右边没有数字。)我们可以编写如下正则表达式:
模式:\d*\.\d* 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 匹配:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^(示例)这匹配
0.
,但它也匹配单个点.
,如上所示。实际上我们想要匹配的是两个不同的字符串类:
- 小数点右侧至少一位数字
- 小数点左边至少有一位数字的数字
模式:\d*\.\d+ 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 匹配:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^
模式:\d+\.\d* 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0. . 匹配:^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^我们发现在这些情况下,引擎都没有找到子字符串
42
、5
、6
或。.
为了获得所需的结果,我们将这些正则表达式组合起来不会有什么坏处。我们怎样才能做到这一点?“or”符号|
允许我们在正则表达式中一次指定多个可能的匹配序列。正如[]
“或”符号允许我们指定替代的单个字符一样,|
我们也可以指定替代的多字符表达式。例如,如果我们想查找“dog”或“cat”,我们可以这样写:
模式:\w\w\w 字符串: 显然,狗是比猫更好的宠物。 匹配:^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^(示例)...但这匹配“word”类的所有三重字符序列。但是“dog”和“cat”甚至没有共同的字母,所以方括号在这里对我们没有帮助。这是我们可以使用的最简单的正则表达式,它既匹配又仅匹配这两个单词:
模式:dog|cat 字符串:显然,狗是比猫更好的宠物。 匹配: ^^^ ^^^(示例)正则表达式引擎首先尝试匹配字符左侧的整个序列
|
,但如果失败,则它会尝试匹配字符右侧的序列|
。多个字符|
也可以链接起来以匹配两个以上的替代序列:
模式:dog|cat|pet 字符串:显然,狗是比猫更好的宠物。 匹配: ^^^ ^^^ ^^^(例子)
现在让我们解决另外几个问题以更好地理解此步骤:
使用符号|
来纠正上面的小数正则表达式以产生如下结果:
图案: 字符串: 0.011 .2 42 2.0 3.33 4.000 5 6 7.89012 0 .. 匹配:^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^(解决方案)使用符号
|
、字符类、“可选”?
等创建一个同时匹配整数和浮点(点)数的单个正则表达式,如上一步末尾的问题中所讨论的(这个问题有点更复杂,是的;))
图案: 字符串: 42L 12 x 3.4f 6l 3.3 0F LF .2F 0。 匹配:^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^(解答) 20个小步骤掌握正则表达式。第 3 部分 RegEx:掌握正则表达式的 20 个简短步骤。第 4 部分
GO TO FULL VERSION