17

我得到一个可以包含文本和数字数据的字符串:

例子:

“100 磅”“我认为是 173 磅”“73 磅”。

我正在寻找一种干净的方法来仅从这些字符串中提取数字数据。

这是我目前正在做的剥离响应:

def stripResponse(String response) {
    if(response) {
        def toRemove = ["lbs.", "lbs", "pounds.", "pounds", " "]
        def toMod = response
        for(remove in toRemove) {
            toMod = toMod?.replaceAll(remove, "")
        }
        return toMod
    }
}
4

6 回答 6

34

您可以使用findAll然后将结果转换为整数:

def extractInts( String input ) {
  input.findAll( /\d+/ )*.toInteger()
}

assert extractInts( "100 pounds is 23"  ) == [ 100, 23 ]
assert extractInts( "I think 173 lbs"   ) == [ 173 ]
assert extractInts( "73 lbs."           ) == [ 73 ]
assert extractInts( "No numbers here"   ) == []
assert extractInts( "23.5 only ints"    ) == [ 23, 5 ]
assert extractInts( "positive only -13" ) == [ 13 ]

如果您需要小数和负数,您可以使用更复杂的正则表达式:

def extractInts( String input ) {
  input.findAll( /-?\d+\.\d*|-?\d*\.\d+|-?\d+/ )*.toDouble()
}

assert extractInts( "100 pounds is 23"   ) == [ 100, 23 ]
assert extractInts( "I think 173 lbs"    ) == [ 173 ]
assert extractInts( "73 lbs."            ) == [ 73 ]
assert extractInts( "No numbers here"    ) == []
assert extractInts( "23.5 handles float" ) == [ 23.5 ]
assert extractInts( "and negatives -13"  ) == [ -13 ]
于 2013-03-22T14:20:27.703 回答
8

把它放在这里给同样需要它的人。

我不需要创建新问题,而是需要一个字符串中的一个数字。

我用正则表达式做到了这一点。

def extractInt( String input ) {
  return input.replaceAll("[^0-9]", "")
}

输入可能在哪里this.may.have.number4.com并返回4

我从上面的答案中收到错误(可能是由于我的 Jenkins 版本)-出于某种原因,我得到了这个: ----它在Jenkinsjava.lang.UnsupportedOperationException: spread not yet supported in input.findAll(\d+)*.toInteger()上说它已解决。

希望这可以帮助。

于 2019-01-15T18:16:21.013 回答
2

通过 metaClass添加下面的方法后numbersFilter,您可以如下调用它:

assert " i am a positive number 14".numbersFilter() == [ 14 ]
assert " we 12 are 20.3propaged 10.7".numbersFilter() == [ 12,20.3,10.7 ]
assert " we 12 a20.3p 10.7 ,but you can select one".numbersFilter(0) == 12
assert " we 12 a 20.3 pr 10.7 ,select one by index".numbersFilter(1) == 20.3

将此代码添加为 BootStrap

String.metaClass.numbersFilter={index=-1->
            def tmp=[];
            tmp=delegate.findAll( /-?\d+\.\d*|-?\d*\.\d+|-?\d+/ )*.toDouble()
            if(index<=-1){
                return tmp;
            }else{
                if(tmp.size()>index){
                    return tmp[index];
                }else{
                   return tmp.last();
                }
            }

}
于 2013-09-14T09:05:44.897 回答
0

由于 input.findAll( /\d+/ )*.toInteger() 不适用于 Jenkins。您可以改用它。

def packageVersion = "The package number is 9.2.5847.1275"
def nextversion=packageVersion.findAll( /\d+/ ).collect{ "$it".toInteger() }
nextversion.add(nextversion.pop()+1)
nextversion = nextversion.join('.')
Result: 9.2.5847.1276
于 2020-11-30T14:46:12.880 回答
0

另一种替代解决方案,没有 RegEx。它将字符串解析为标记并将它们转换为数字列表或空值。删除空值,最后只考虑第一个条目(根据需要)。

def extractNumericData(String response) {
    response.split(' ')
        .collect { it.isFloat() ? Float.parseFloat(it) : null }
        .findAll { it }
        .first()
}

assert 100 == extractNumericData("100 pounds")
assert 173 == extractNumericData("I think 173 lbs")
assert 73 == extractNumericData("73 lbs.")
于 2020-11-30T17:54:47.487 回答
-1

当逐行解析 String.contains 和 String.replaceAll (用空格替换所有非数字字符序列)时,String.split() 组合很有用,如下所示:

if (line.contains("RESULT:")) {
    l = line.replaceAll("[^0-9][^0-9]*"," ")
    a = l.split()
    pCount1 = Integer.parseInt(a[0])
    pCount2 = Integer.parseInt(a[1])
}

String.findAll 解决方案更好!相等的:

if (line.contains("RESULT:")) {
    a = line.findAll( /\d+/ )*.toInteger()
    pCount1 = a[0]
    pCount2 = a[1]
}
于 2020-01-09T18:36:20.077 回答