JavaRush /Java 博客 /Random-ZH /RegEx:掌握正则表达式的 20 个简短步骤。第2部分
Artur
第 40 级
Tallinn

RegEx:掌握正则表达式的 20 个简短步骤。第2部分

已在 Random-ZH 群组中发布
RegEx:掌握正则表达式的 20 个简短步骤。第 1 部分 原文在这里 在上一部分中我们掌握了最简单的正则表达式,并且已经学到了一些东西。在这一部分中,我们将研究稍微复杂的设计,但相信我,它不会像看起来那么困难。 RegEx:掌握正则表达式的 20 个简短步骤。 第 2 - 1 部分那么让我们继续吧!

第 8 步:星号*和加号+

RegEx:掌握正则表达式的 20 个简短步骤。 第 2 - 2 部分到目前为止,我们或多或少只能匹配给定长度的字符串。但在最近的问题中,我们已经接近了迄今为止我们所看到的符号的极限。例如,假设我们不限于 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.,因为我们需要小数点右边至少一位数字才能匹配。

像往常一样,让我们​​解决几个简单的问题:

找出下面段落中的所有英语单词。
图案:
字符串:33是 6,但4加 3 是7
匹配:    ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^ 
解决方案)在下面的列表中找到所有文件大小符号。文件大小将由一个数字(带或不带小数点)后跟KBMB或组成: GBTB
图案:
字符串:   11TB 13 14.4MB 22HB 9.9GB TB 0KB
匹配:^^^^ ^^^^^^ ^^^^^ ^^^  
解决方案

第9步:“可选”问号?

RegEx:掌握正则表达式的 20 个简短步骤。 第 2 - 3 部分您已经编写了正则表达式来解决最后一个问题吗?有效吗?现在尝试在这里应用它:
图案:
字符串: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/Lf/F来指示它们应该(分别)被视为 long/float,而不是常规的 int/double。在下面的行中找到所有有效的“长”数字:
图案:
字符串:   13L long 2l 19 L lL 0
匹配:^^^ ^^ ^^ ^ 
解决方案

第10步:“或”号|

RegEx:掌握正则表达式的 20 个简短步骤。 第 2 - 4 部分在第 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.,但它也匹配单个点.,如上所示。实际上我们想要匹配的是两个不同的字符串类:
  1. 小数点右侧至少一位数字
  2. 小数点左边至少有一位数字的数字
让我们编写以下两个相互独立的正则表达式:
模式:\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. .
匹配:^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ 
我们发现在这些情况下,引擎都没有找到子字符串4256或。.为了获得所需的结果,我们将这些正则表达式组合起来不会有什么坏处。我们怎样才能做到这一点?“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 部分
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION