如何在Groovy中获取字符串每行的第一个字

如何在Groovy中获取字符串每行的第一个字,groovy,jenkins-pipeline,Groovy,Jenkins Pipeline,我有一个方法,它返回一个包含多行的字符串。我想解析字符串并得到每行的第一个单词 方法getText()返回: Lorem ipsum dolor sit amet odio magnis vitae iaculis 我只想 Lorem sit magnis 我现在的代码是 def projectString = getText() def projects = projectString.substring(0, projectString.indexOf

我有一个方法,它返回一个包含多行的字符串。我想解析字符串并得到每行的第一个单词

方法
getText()
返回:

Lorem ipsum dolor 
sit amet odio 
magnis vitae iaculis
我只想

Lorem
sit
magnis
我现在的代码是

        def projectString = getText()
        def projects = projectString.substring(0, projectString.indexOf(' '))
当然,这只能得到第一行的第一个单词。我可以在基于新行的字符串上使用while循环,并使用上面的
substring
方法获取第一个单词,但我感觉Groovy有一种更为Groovy的方法来实现这一点

最初我考虑在方法调用结果上使用管道

def projects = getText() | sh "awk '{print $1}'"
但我无法让它工作。

以下是一个示例:

def projectString = """Lorem ipsum dolor
sit amet odio
magnis vitae iaculis"""

projectString = projectString
    .readLines()
    .collect { it[0.. it.indexOf(' ')] }
    .join("\n")

println projectString
您可以在线查看:

以下是一个示例:

def projectString = """Lorem ipsum dolor
sit amet odio
magnis vitae iaculis"""

projectString = projectString
    .readLines()
    .collect { it[0.. it.indexOf(' ')] }
    .join("\n")

println projectString

您可以在线查看它:

Groovy具有与Perl类似的正则表达式模式的模式操作符
~
。下面的解决方案使用
(?m)
启用多行标志,并使用
^\w+
在字符串开头获取一个或多个[A-Za-z0-9]。regex表达式的计算结果为Matcher对象,从该对象开始,所有匹配项(每行的第一个字)被收集到一个列表中

第二种解决方案首先使用readLines()返回行列表,然后使用collect()的闭包重载使用StringTokenizer将每行映射/转换为每行的第一个字,这比典型的字符串拆分更快。此外,API似乎建议基于其流式接口进行延迟计算,这比解析整行代码要好,因为我们只需要第一个单词

举例如下:

def foo = """Lorem ipsum dolor
sit amet odio
magnis vitae iaculis"""

println((foo =~ /(?m)^\w+/).collect())
println foo.readLines().collect { new StringTokenizer(it).nextElement() }

// both print [Lorem, sit, magnis]

Groovy具有与Perl类似的正则表达式模式的模式运算符
~
。下面的解决方案使用
(?m)
启用多行标志,并使用
^\w+
在字符串开头获取一个或多个[A-Za-z0-9]。regex表达式的计算结果为Matcher对象,从该对象开始,所有匹配项(每行的第一个字)被收集到一个列表中

第二种解决方案首先使用readLines()返回行列表,然后使用collect()的闭包重载使用StringTokenizer将每行映射/转换为每行的第一个字,这比典型的字符串拆分更快。此外,API似乎建议基于其流式接口进行延迟计算,这比解析整行代码要好,因为我们只需要第一个单词

举例如下:

def foo = """Lorem ipsum dolor
sit amet odio
magnis vitae iaculis"""

println((foo =~ /(?m)^\w+/).collect())
println foo.readLines().collect { new StringTokenizer(it).nextElement() }

// both print [Lorem, sit, magnis]

it[0..it.indexOf(“”)]
看起来很奇怪。。。我更喜欢
it.split().head()
工作起来很有魅力。我在@tim_yates的建议中使用了
it.split().head()
我不知道是谁否决了我下面的帖子,但我提供了两个单行解决方案,它们使用不同的方法实现了与此解决方案相同的目标。在b.c.的否决票中,它通常会立即被视为一个不正确的解决方案,而这绝对不是…
it[0..it.indexOf(“”)]
看起来很奇怪。。。我更喜欢
it.split().head()
工作起来很有魅力。我在@tim_yates的建议中使用了
it.split().head()
我不知道是谁否决了我下面的帖子,但我提供了两个单行解决方案,它们使用不同的方法实现了与此解决方案相同的目标。b.c.的否决票,它通常会立即被视为一个不正确的解决方案,这绝对不是…嗯,不知道为什么会被否决。它以两种不同的简单方式完成OP想要做的事情,在每个示例中只使用一行代码。至少尝试一下。顺便说一句,您可能希望根据要匹配的内容将
\w
切换到
\S
\S
更宽松,因为它将匹配任何非空白字符。您是否检查过javadocs中的StringTokenizer?这是一个旧的遗留实现。“StringTokenizer是一个出于兼容性原因保留的遗留类,尽管在新代码中不鼓励使用它。建议寻求此功能的任何人使用String的拆分方法或java.util.regex包。”我理解,一开始我真的在考虑使用一个通用的字符串拆分,但我读到了这个:。总之,分析结果表明StringTokenizer的速度几乎是split()的2倍。如果您不需要其余的标记或正则表达式,为什么还要麻烦使用split呢?那只是多余的工作。嗯,不知道为什么这会被否决。它以两种不同的简单方式完成OP想要做的事情,在每个示例中只使用一行代码。至少尝试一下。顺便说一句,您可能希望根据要匹配的内容将
\w
切换到
\S
\S
更宽松,因为它将匹配任何非空白字符。您是否检查过javadocs中的StringTokenizer?这是一个旧的遗留实现。“StringTokenizer是一个出于兼容性原因保留的遗留类,尽管在新代码中不鼓励使用它。建议寻求此功能的任何人使用String的拆分方法或java.util.regex包。”我理解,一开始我真的在考虑使用一个通用的字符串拆分,但我读到了这个:。总之,分析结果表明StringTokenizer的速度几乎是split()的2倍。如果您不需要其余的标记或正则表达式,为什么还要麻烦使用split呢?我不知道是谁否决了我下面的帖子,但我提供了两个一行解决方案,它们使用不同的方法实现了与所选解决方案相同的目标。b.c.的否决票,它通常会立即被视为一个不正确的解决方案,这绝对不是…我不知道是谁否决了我下面的帖子,但我提供了两个一行解决方案,它们使用不同的方法实现了与所选解决方案相同的目标。和b.c.的否决票,这将是一般性的