【问题标题】:Splitting a string using a delimiter in Groovy and avoiding IndexOutOfBoundsException在 Groovy 中使用分隔符拆分字符串并避免 IndexOutOfBoundsException
【发布时间】:2018-11-17 17:12:41
【问题描述】:

我想将输入参数inputDetails 拆分为单元级别。我正在使用 tokenize 来执行此操作。这是我的代码:

Groovy 代码:

def inputDetails = "1234-a0-12;1111-b0-34";
def cDesc = inputDetails.tokenize(";");
for (int i=0; i<cDesc.size(); ++i)
{
    def cVer = cDesc.get(i);
    def cNum = cVer.tokenize("-");
    def a = cNum.get(0);
    def b = cNum.get(1);
    def c = cNum.get(2);

    println (" DEBUG : Input details are, ${a} : ${b} : ${c} \n");
}

输出:

 DEBUG : Input details are, 1234 : a0 : 12 

 DEBUG : Input details are, 1111 : b0 : 34

此输出正确且符合预期。但是,如果我将 Groovy 代码的第一行更改为以下内容:

def inputDetails = "1234-a0-12;1111-b0";

我收到以下错误消息:

 java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
    at java_util_List$get$6.call(Unknown Source)
    at Script1.run(Script1.groovy:9)

如何解决它以防止在同时支持 1234-a0-12;1111-b0-34 和 1234-a0-12;1111-b0 输入的同时获得 IndexOutOfBoundsException?

【问题讨论】:

    标签: jenkins groovy jenkins-pipeline jenkins-groovy groovy-console


    【解决方案1】:

    您可以使用 Groovy 的 multiple assignment 功能从第二个标记化中安全地获取 3 个值。考虑以下示例:

    def inputDetails = "1234-a0-12;1111-b0-34"
    
    def cDesc = inputDetails.tokenize(";")
    
    cDesc.each { part ->
        def (p1, p2, p3) = part.tokenize('-')
    
        println "DEBUG: Input details are, ${p1} : ${p2} : ${p3}"
    }
    

    输出:

    DEBUG: Input details are, 1234 : a0 : 12
    DEBUG: Input details are, 1111 : b0 : 34
    

    好消息是这种方法可以防止IndexOutOfBoundsException 或NullPointerException。如果我们将第一行改为

    def inputDetails = "1234-a0-12;1111-b0"
    

    结果是:

    DEBUG: Input details are, 1234 : a0 : 12
    DEBUG: Input details are, 1111 : b0 : null
    

    【讨论】:

    • 感谢 Szymon 使问题陈述和建议的解决方案更有意义。
    • groovy 的原作者没有决定改用froody,这是一个错失的机会
    【解决方案2】:

    您可以通过在'-'上进一步拆分将字符串拆分为二维列表:

    def inputDetails = "1234-a0-12;1111-b0-34"
    def elements = inputDetails.split(';').collect{it.split('-')}
    

    elements 的类型为 List&lt;List&lt;String&gt;&gt;。打印时,它会产生:

    [[1234, a0, 12], [1111, b0, 34]]
    

    有了这个,您可以获得更大的灵活性,而不是硬编码数组索引。

    与"1234-a0-12;1111-b0" 一起,它被拆分为[[1234, a0, 12], [1111, b0]]

    【讨论】:

    • 您好 Ernest,您建议拆分成二维数组有效,但结果是我输入的数组形式:[[1234, a0, 1​​2], [1111, b0, 34]]。我想将每个元素用于不同的目的,我如何获得 1234、a0、12.. 作为单独的元素。
    • @Yash 这只是一个普通的列表列表。您可以只做一个 for-each:elements.each{list -&gt; def a = list[0]; def b = list[1], }... 并且您可以检查列表的长度以了解它包含多少元素。
    • 感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 2021-11-08
    • 2011-12-26
    相关资源
    最近更新 更多