2015-03-25 51 views
4

我是Groovy的新手,有關於關閉的replaceFirst的問題。如何使用Groovy的replaceFirst與閉包?

groovy-jdk API doc給我的......

assert "hellO world" == "hello world".replaceFirst("(o)") { it[0].toUpperCase() } // first match 
assert "hellO wOrld" == "hello world".replaceAll("(o)") { it[0].toUpperCase() } // all matches 

assert '1-FISH, two fish' == "one fish, two fish".replaceFirst(/([a-z]{3})\s([a-z]{4})/) { [one:1, two:2][it[1]] + '-' + it[2].toUpperCase() } 
assert '1-FISH, 2-FISH' == "one fish, two fish".replaceAll(/([a-z]{3})\s([a-z]{4})/) { [one:1, two:2][it[1]] + '-' + it[2].toUpperCase() } 

前兩個例子是很簡單的例子,但我不明白,其餘的。

首先,[one:1, two:2]是什麼意思? 我甚至不知道要搜索的名稱。

二,爲什麼有「它」的列表? 該文檔說replaceFirst()

用該文本上的閉包調用的結果替換捕獲的組的第一次出現。

不是「它」是指「被捕獲組的第一次出現」嗎?

我會很感激任何提示和意見!

回答

2

首先,[one:1, two:2]是Map:

assert [one:1, two:2] instanceof java.util.Map 
assert 1 == [one:1, two:2]['one'] 
assert 2 == [one:1, two:2]['two'] 
assert 1 == [one:1, two:2].get('one') 
assert 2 == [one:1, two:2].get('two') 

所以,基本上,閉包中的代碼使用地圖作爲查找表1two2取代one

其次,讓我們來看看如何regex matcher works

要找出有多少基存在於表達,調用匹配對象的 groupCount方法。 groupCount方法返回一個int,表示匹配器的 模式中存在的捕獲組的數量。在此示例中,groupCount將返回數字4, ,表明該模式包含4個捕獲組。

還有一個特殊的組,組0,它始終代表整個表達式。該組不包括在由 groupCount報告的總數中。 ?組與(開始是純粹的,非捕獲組 不捕捉文本和不計入團體總分計

鑽探到正則表達式的東西:

def m = 'one fish, two fish' =~ /([a-z]{3})\s([a-z]{4})/ 
assert m instanceof java.util.regex.Matcher 
m.each { group -> 
    println group 
} 

這產生:

[one fish, one, fish] // only this first match for "replaceFirst" 
[two fish, two, fish] 

,所以我們可以更清晰的方式重命名由groupit重寫代碼(it僅僅是default name of the argument in a single argument closure):

assert '1-FISH, two fish' == "one fish, two fish".replaceFirst(/([a-z]{3})\s([a-z]{4})/) { group -> 
    [one:1, two:2][group[1]] + '-' + group[2].toUpperCase() 
} 
assert '1-FISH, 2-FISH' == "one fish, two fish".replaceAll(/([a-z]{3})\s([a-z]{4})/) { group -> 
    [one:1, two:2][group[1]] + '-' + group[2].toUpperCase() 
}