简体   繁体   English

如何使用Groovy的replaceFirst与闭包?

[英]How to use Groovy's replaceFirst with closure?

I'm a newbie on Groovy and have a question about replaceFirst with closure. 我是Groovy的新手,并且有关于replaceFirst和闭包的问题。

The groovy-jdk API doc gives me examples of... 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() }

The first two examples are quite straightforward, but I can't understand the remaining ones. 前两个例子非常简单,但我无法理解其余的例子。

First, what does [one:1, two:2] mean? 首先, [one:1, two:2]是什么意思? I even don't know the name of it to search. 我甚至不知道要搜索它的名字。

Second, why is there a list of "it"? 第二,为什么有“它”列表? The doc says replaceFirst() doc说replaceFirst()

Replaces the first occurrence of a captured group by the result of a closure call on that text. 通过对该文本的闭包调用的结果替换捕获的组的第一个匹配项。

Doesn't "it" refer to "the first occurrence of a captured group"? “它”不是指“被捕组首次出现”吗?

I would appreciate any tips and comments! 我将不胜感激任何提示和评论!

First, [one:1, two:2] is a Map: 首先, [one:1, two:2]是一张地图:

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')

So, basically, the code inside the closure uses that map as a lookup table to replace one with 1 and two with 2 . 因此,基本上,封闭内部的代码使用地图为查找表 ,以取代one1two2

Second, let's see how the regex matcher works : 其次,让我们看看正则表达式匹配器是如何工作的

To find out how many groups are present in the expression, call the groupCount method on a matcher object. 要查找表达式中存在多少个组,请在匹配器对象上调用groupCount方法。 The groupCount method returns an int showing the number of capturing groups present in the matcher's pattern. groupCount方法返回一个int,显示匹配器模式中存在的捕获组数。 In this example, groupCount would return the number 4, showing that the pattern contains 4 capturing groups. 在此示例中,groupCount将返回数字4,表示该模式包含4个捕获组。

There is also a special group, group 0, which always represents the entire expression. 还有一个特殊组,即组0,它始终代表整个表达式。 This group is not included in the total reported by groupCount. 该组未包含在groupCount报告的总数中。 Groups beginning with (? are pure, non-capturing groups that do not capture text and do not count towards the group total. 以(?开头的组是纯粹的非捕获组,不捕获文本而不计入组总数。

Drilling down to the regex stuff: 深入到正则表达式的东西:

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
}

This yields: 这会产生:

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

So we can rewrite the code in a clearer way renaming it by group ( it is simply the default name of the argument in a single argument closure ): 所以我们可以更清楚地重写代码,按group重命名itit只是单个参数闭包中参数默认名称 ):

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()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM