简单的Groovy控制台解析问题

Geo*_*ith 1 groovy

我刚开始使用Groovy.我确信我错过了一些愚蠢的东西.有人能告诉我为什么这个代码在groovy控制台中失败了吗?它认为输入字符串中只有14个单词和1行.

def input = """
line1: 50 65 42
line2: 123 456 352 753 1825
line3: 10 25 20 48 107
"""

words = input.split(/ /)
lines = input.split(/^/)
assert words.size() == 16
assert lines.size() == 3
Run Code Online (Sandbox Code Playgroud)

epi*_*ian 5

在第一个的情况下assert,错误消息可以提示问题所在:

Assertion failed: 

assert words.size() == 16
       |     |      |
       |     14     false
       [
       line1:, 50, 65, 42
       line2:, 123, 456, 352, 753, 1825
       line3:, 10, 25, 20, 48, 107
       ]
Run Code Online (Sandbox Code Playgroud)

那里有一些逗号,并且words打印值的方式似乎是错误的.发生的事情是input.split(/ /)将输入字符串拆分为空格,但由于它还包含换行符,因此某些字词不会被拆分,例如'42\nline2:'.

为了更清楚地看到这一点,我们可以使用该inspect方法,它为我们提供了一个字符串形式的字符串:

println input.inspect()
// --> '\nline1: 50 65 42\nline2: 123 456 352 753 1825\nline3: 10 25 20 48 107\n'

println input.split(/ /).inspect()
// --> ['\nline1:', '50', '65', '42\nline2:', '123', '456', '352', '753', '1825\nline3:', '10', '25', '20', '48', '107\n']
Run Code Online (Sandbox Code Playgroud)

要通过空格分割单词,Groovy会添加一个方便的非参数化split方法:

def words = input.split()
assert words.size() == 16
println words.inspect()
// --> ['line1:', '50', '65', '42', 'line2:', '123', '456', '352', '753', '1825', 'line3:', '10', '25', '20', '48', '107']
Run Code Online (Sandbox Code Playgroud)

并获得您可以使用的字符串行readLines.

def lines = input.readLines()
println lines.inspect()
// --> ['', 'line1: 50 65 42', 'line2: 123 456 352 753 1825', 'line3: 10 25 20 48 107']
Run Code Online (Sandbox Code Playgroud)

请注意,然而,这readLines将返回四个元素,因为有第一个空行(我不知道为什么它忽略了最后一个空行),所以assert lines.size() == 3仍然会失败.

您可以Collection#findAll()在结果列表中过滤掉这些空行,或String#findAll(Pattern)直接在输入字符串上调用:

def lines = input.readLines().findAll()
assert lines.size() == 3

def lines2 = input.findAll(/\S+/)
assert lines2.size() == 3

assert lines == lines2
Run Code Online (Sandbox Code Playgroud)