如果你在Java编码时使用过正则表达式,那么会发现Groovy对正则表达式的用法做了很大的简化,从而让更多的人不再惧怕正则表达式。Ted Naleid的博文中,详细介绍了Groovy中正则表达的用法。
用/../定义正则表达式
Groovy中使用slashy(斜线)语法“//”定义正则表达式,对于出现在表达式中特殊字符,会自动进行转义。比如:
assert java.lang.String == /foo/.class
assert ( /Count is d/ == "Count is \d" )
“//”中也可以使用GString,比如:
def name = "Ted Naleid"
assert ( /$name/ == "Ted Naleid" )
assert ( /$name/ == "$name" )
操作符
~:用在字符串之前,会将字符串编译成Pattern。比如:
def shoutedWord = ~/b[A-Z]+b/
=~:将操作符左边的字符串跟右边的Pattern进行局部匹配,返回值为Matcher。如:
def matcher=("finda" =~ /find/)
assert "find"==matcher[0]
==~:用法跟=~类似,只是这里进行的精确匹配,即左边的整个字符串跟左边的模式进行匹配,==~的结果跟Matcher.matches()的结果是一样的。返回值为Boolean。如:
def matcher=("finda"==~ /find/)
assert java.lang.Boolean==matcher.getClass()
对字符串的改进
replaceFirst:将满足正则表达式的第一个字符串进行替换,比如:
assert "Green Eggs and Spam" == "Spam Spam".replaceFirst(/Spam/, "Green Eggs and")
replaceAll:将所有满足正则表达式的字符串进行替换,比如:assert "The armor was colored silver" == "The armour was coloured silver".replaceAll(/ou/, "o")
replaceAll的第二个参数可以使用闭包,但需要注意,闭包中的第一个参数是匹配的字符串,比如:
def dashedToCamelCase(orig) {
orig.replaceAll(/-(w)/) { fullMatch, firstCharacter -> firstCharacter.toUpperCase() }
}
assert "firstName" == dashedToCamelCase("first-name")
对集合的改进
Groovy中除了each、collect、inject等,还有一个对正则表达式敏感的迭代器:grep,即在集合中查找满足表达式的元素。比如:
assert ["foobar", "bazbar"] == ["foobar", "bazbar", "barquux"].grep(~/.*bar$/)
//如下是使用findAll方法实现同样的功能的代码:
assert ["foobar", "bazbar"] == ["foobar", "bazbar", "barquux"].findAll { it ==~ /.*bar$/ }
Matcher的用法
我们已经知道了=~操作符会返回一个Matcher对象。许多示例中都是将这个Matcher当作一个List来使用,比如:
def matcher = "foobazaarquux" =~ "o(b.*r)q"
assert ["obazaarq", "bazaar"] == matcher[0]
assert "bazaar" == matcher[0][1]
上述代码的用法有一个缺陷,如果没有匹配内容,matcher[0]就会返回一个错误信息。那么在使用matcher[0]之前,调用matches()做一下判断如何?
def matcher = "foobazaarquux" =~ "o(b.*r)q"
def lst=[]
if(matcher.matches()){
list=matcher[0]
}
assert ["obazaarq", "bazaar"]==lst //FALSE
为什么assert是false?那就需要了解一下matches()的真正涵义了。matches()仅用来检查整个字符串是否跟正则表达式匹配。对于上述代码,将正则表达式修改为: ".*(b.*r).*",就可以了。所以安全起见,可以使用getCount()来查看匹配的个数。
对于用在集合上的each、collect,、inject, findAll等方法,对于Matcher对象同样适用。比如
("foo1 bar30 foo27 baz9 foo600" =~ /foo(d+)/).each { match, digit -> println "+$digit" }
看完本文,对Groovy中使用正则表达式有了清晰的了解?!那就勇敢的在你的Groovy代码中使用正则表达式吧!*_^
关于本文详细内容,请参见原文。



