Groovy提取字符之前的子字符串

23

我有一堆像这样的字符串

asdf v1.0
jkl v3.04

所有我的字符串都由一组字符后跟一个空格、然后是“v”和一个数字组成。我想从每个字符串中提取出在“v”之前以及在“v”前面的空格字符之前的部分,以便:

asdf v1.0 becomes 'asdf'
jkl v3.04 becomes 'jkl'

我只是需要一些帮助。我尝试过takeWhile { it != 'v' },但它会包括结果字符串中的'v'前面的空格,而我不想要这个。


"asdf v1.0".split()[0] 应该是好的。 - dmahapatro
如果引导字符串中有空格,则此解决方案将失败。对于输入John Kramer v12.2,我认为应该返回“John Kramer”,但您的解决方案却只返回了“John”。 - BalRog
4个回答

48

您可以简单地提取子字符串:

input.substring(0, input.lastIndexOf(" v"))
得到 v 后面的部分:
input.substring(input.lastIndexOf(" v") + 2)

在我看来,这个解决方案也是失败了的。如果输入为Kramer v Kramer v8.8,我认为期望的结果应该是"Kramer v Kramer"。然而,这个解决方案会返回"Kramer" - BalRog
@BalRog 在这种情况下,String#lastIndexOf 应该可以解决问题。已更新答案。 - M A
1
这并不是很流畅的代码,你可以像这样做:input[0..-input.lastIndexOf(" v")-1] - Daniel Bo

5
我认为,根据所述标准,在所选解决方案无法正确解决的地方,以下内容会给出正确的结果:
String stringParser(String inputString) {
    inputString ? inputString.split(/ v\d/)[0] : ''
}

一些样例测试:

assert stringParser('John Kramer v1.1') == 'John Kramer'
assert stringParser('Kramer v Kramer v9.51') == 'Kramer v Kramer'
assert stringParser('A very hungry caterpillar v2.6') == 'A very hungry caterpillar'

2
你总是可以搞砸它: "Best v3rsion v3.0", 这里有一个更好的尝试,与 @manouti 的更新版本在语义上相同: (input =~ /(.*) v/)[0][1]。贪婪的 .* 给出了最佳结果,因为我们需要最后一个 vX.X[0] 是第一个匹配项,[1] 是第一组(括号中的内容)。 - TWiStErRob

2

这里是一个使用正则表达式的例子

String regex = /(v\d)(\d|\.)*/

def clean = { text ->
   text?.replaceAll(regex,'')?.trim()
}

assert 'v1.11' ==~ regex

assert clean(null) == null
assert clean('asdf v1.0') == 'asdf'
assert clean('jkl v3.04') == 'jkl'
assert clean('John Kramer v1.1') == 'John Kramer'
assert clean('Kramer v Kramer v9.51') == 'Kramer v Kramer'
assert clean('A very hungry caterpillar v2.6') == 'A very hungry caterpillar'


2

input[0..(input.lastIndexOf('v') - 1)].trim()

细节

这段代码用于从输入字符串中提取出除最后一个字母"v"之外的所有字符,并去除首尾空格。

String str = 'jkl v3.04'

// index of last "v" char is 4
assert str[4..-1] == 'v3.04'
assert str[0..(4 - 1 )].trim() == 'jkl'

不必惊讶:我是一位非常老的Groovy程序员。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接