在groovy中,我有两个多行字符串:
String input1 = """
test: task ':test'
version: 1.1.0.1
targetCompatibility: 1.8
""".stripIndent()
String input2 = """
test: task ':test'
version: latest
testResultsDirName: test-results
targetCompatibility: 1.8
""".stripIndent()
我需要提取version:
之后的任何文本,并想出了这个方法:
String getProjectVersion(String input, String prefix){
String result = "Unknown"
if (input.contains(prefix)) {
def list = input.readLines()
def all = list.findAll { s -> s =~ prefix }[0]
result = all - prefix
}
return result
}
给出了上述输入:
String prefix = "version:"
println getProjectVersion(input1, prefix)
println getProjectVersion(input2, prefix)
打印:
1.1.0.1
latest
这太棒了!
但是,有没有一种更紧凑的方法可以实现相同的,而不必创建特殊的正则表达式模式,这些模式可能可以在一行中完成所有操作,但对于不熟悉正则表达式的人来说却无法理解?
似乎可以使用一个非常简单的正则表达式,使用提取单词version:
之后的字符串
String getProjectVersion(String input){
def m = input =~ /version:h*(.+)/
if (m) {
return m.group(1);
}
return "Unknown"
}
请参阅Groovy演示。
这里,version:h*(.+)
模式匹配version:
,然后匹配任何零个或多个水平空白(这样您就可以保持在同一行上(,然后将捕获到组1中(请参见m.group(1)
(,尽可能多地捕获除换行符之外的任何一个或更多个字符(使用(.+)
(。
如果Group 1匹配,则返回值为Group 1值,否则返回值为Unknown
。
如果您要从相同的输入中获取不同的值,最好将输入转换为Map对象,这样可以更快地访问
String input1 = """
test: task ':test'
version: 1.1.0.1
targetCompatibility: 1.8
#
""".stripIndent()
def toMap(String s){
def p = /(w+):s*(.*)/
s.readLines().collect{it=~p}.findAll{it}.collectEntries{ [ it[0][1], it[0][2].trim()]}
}
def m1 = toMap(input1)
println m1.version
println m1.test
或者您可以读取格式为:从外观上看是:YAML的数据。
println(new groovy.yaml.YamlSlurper().parseText(input1)["version"])
// → latest