Skip to end of metadata
Go to start of metadata

正则表达式(Regular Expressions)

正则表达式是处理文本的“瑞士军刀”。它为程序员提供了从字符串中匹配和提取 模式(patterns) 的功能。最简单的正则表达式是包含字符和数字的字符串。而且最简单的表达式使用 ==~ 操作符来操作正则表达式。所以例如要匹配‘potato’的“丹奎尔拼写”:

在 groovyConsole 中打入上面代码并运行,它的求值是 true。有一些需要注意的事,首先是 ==~ 操作符,这和 == 操作符类似,不过是用来匹配模式而不是判断精确相等的。第二个是正则表达式括在 / 中,这是告诉 Groovy(也是任何读代码的人)这是正则表达式,而不仅仅是字符串。

但是比方说我们还想匹配正确的拼写,就需要在‘e’后面加一个‘?’表示 e 是可有可无的。下面的求值也是 true。

正确的拼写也可以匹配:

不过其它的就不能匹配了:

这就是如何定义一个使用正则表达式的布尔表达式。下面我们做些更难的。定义一个检查正则表达式的方法。例如,我们写一些代码匹配 Pete Wisniweski 的姓氏:

我们又接触一些新东西。第一个是定义了一个函数(function)-其实是方法(method),不过我把它们当作一回事(actually a method, but I'll use the two words interchangably)。函数类似闭包是一堆代码。函数总是有名字的,而闭包可以是匿名的。定义好这个函数后,后面就可以多次使用了。

在这个函数中, if 语句使用 ==~ 操作符检查参数 spellingAttempt 是否匹配给定的正则表达式。

我们再写个更复杂的。比如要匹配一个可能没有中间那个‘w’的字符串,可以:

在 spellingRegularExpression 中加了一个 ?,表示在它前面的那个元素(字符‘w’)是可选的(可以有也可以没有)。运行代码时为 spellingAttempt 使用不同的拼写,可以看到现在只有两个拼写“Wisniewski”和“Wisnieski”可以通过检查。(注意,checkSpelling 函数的定义要保留在 groovyConsole 的顶部)

? 是正则表达式中有特殊含义字符中的一个。你可以假设任何标点符号都是有特殊含义的。

现在让中间的“ie”交换了位置也可以通过拼写检查。考虑以下代码:

再次运行拼写检查。这次有4个词通过检查“Wisniewski”、“Wisneiwski”、“Wisnieski”和“Wisneiski”。竖线字符‘|’意思是左边或者右边都可以,这里是“ie”或“ei”。用括号标识这部分的开始和结束。

最后一个有趣的特性是指定一组字符,任意一个匹配都可以。这要使用方括号 [] 。尝试以下正则表达式,使用不同的 Pete 的姓氏的错误拼写:

最后一个要解释一下。如果在方括号中的第一个字符是 ^ 意思是除了方括号中给出字符的任意其它字符。

操作符

现在大概知道正则表达式是如何工作的了,你会发现操作符非常有用,看看它们能做什么:

正则表达式操作符

表达式

匹配说明

匹配结果

a?

匹配 0 个或 1 个 a

'a' 或者空字符串

a*

匹配 0 个或多个 a

空字符串或 'a', 'aa', 'aaa' 等

a+

匹配 1 个或多个 a

'a', 'aa', 'aaa' 等

a|b

匹配 ab

'a' 或 'b'

.

匹配任意单个字符

'a', 'q', 'l', '_', '+', 等

[woeirjsd]

匹配给定字符中的任意一个

'w', 'o', 'e', 'i', 'r', 'j', 's', 'd'

[1-9]

匹配范围内的任意一个字符

'1', '2', '3', '4', '5', '6', '7', '8', '9'

[^13579]

匹配除了给定字符外的任意字符

偶数, 或其它字符

(ie)

分组一个表达式(和其它操作符一起使用)

'ie'

^a

匹配以 a 开头的行

'a'

a$

匹配以 a 结尾的行

'a'

还有些事应该知道。如果要使用上面这些操作符本身,比如要匹配一个问号,就需要在它前面放一个‘\’,例如:

这是你第一个真正丑陋的表达式。(这些在 PERL 中频繁使用的原因是,它是一个“只写”的语言。)顺便说一下,google 知道有多高。理解像这样表达式的唯一方法是把它分解开:

/

[^?]

+

?

/

表达式开始

除了 '?' 的任意字符

至少一个

问号

表达式结束

所以要在 ? 前加一个 \,这样它就代表一个实际的问号了。

  • No labels