如何从字符串中提取数字并获取整数数组?

How to extract numbers from a string and get an array of ints?

提问人:John Manak 提问时间:3/3/2010 最后编辑:OneCricketeerJohn Manak 更新时间:12/4/2022 访问量:286552

问:

我有一个 String 变量(基本上是一个带有未指定数字数量的英语句子),我想将所有数字提取到一个整数数组中。我想知道是否有正则表达式的快速解决方案?


我使用了 Sean 的解决方案并稍微更改了一下:

LinkedList<String> numbers = new LinkedList<String>();

Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher(line); 
while (m.find()) {
   numbers.add(m.group());
}
Java 正则表达式

评论

1赞 Buhake Sindi 3/3/2010
数字是否被空格或其他字符包围?数字是如何格式化的,它们是十六进制、八进制、二进制、十进制?
0赞 John Manak 3/3/2010
我认为从问题中可以清楚地看出:这是一个带有数字的英语句子。此外,我说的是整数数组,所以我要找的是整数。

答:

4赞 Andrey 3/3/2010 #1

对于有理数,请使用以下一个:(([0-9]+.[0-9]*)|([0-9]*.[0-9]+)|([0-9]+))

评论

1赞 Alan Moore 3/3/2010
OP说的是整数,而不是实数。此外,您忘记了转义点,并且这些括号都不是必需的。
187赞 Sean Owen 3/3/2010 #2
Pattern p = Pattern.compile("-?\\d+");
Matcher m = p.matcher("There are more than -2 and less than 12 numbers here");
while (m.find()) {
  System.out.println(m.group());
}

...prints 和 .-212


-?匹配前导负号 -- 可选。\d 匹配一个数字,但我们需要像在 Java 字符串中一样编写。因此,\d+ 匹配 1 位或多位数字。\\\

评论

4赞 OscarRyz 3/3/2010
你能通过解释你的正则表达式来补充你的答案吗?
3赞 Sean Owen 3/3/2010
-?匹配前导负号 -- 可选。\d 匹配一个数字,我们需要在 Java 字符串中将 \ 写成 \\。所以, \\d+ 再匹配 1 位数字
8赞 jlengrand 6/13/2012
我将表达式更改为 Pattern.compile(“-?[\\d\\.]+“) 来支持浮点数。你绝对带我上路,谢谢!
0赞 Mugoma J. Okomba 3/9/2016
此方法检测数字,但不检测格式化的数字,例如 .对于此类用途2,000-?\\d+,?\\d+|-?\\d+
0赞 Sean Owen 3/10/2016
它只支持一个逗号,所以会错过“2,000,000”。它还接受像“2,00”这样的字符串。如果必须支持逗号分隔符,则: 应该有效。-?\\d+(,\\d{3})*
19赞 sidereal 3/3/2010 #3
Pattern p = Pattern.compile("[0-9]+");
Matcher m = p.matcher(myString);
while (m.find()) {
    int n = Integer.parseInt(m.group());
    // append n to list
}
// convert list to array, etc

您实际上可以用 \d 替换 [0-9],但这涉及双反斜杠转义,这使得阅读更加困难。

评论

0赞 sidereal 3/3/2010
哎 呦。肖恩处理负数,所以这是一个改进。
2赞 cegprakash 10/22/2013
如果您使用“-?[0-9]+"
10赞 Kannan 2/10/2012 #4
  StringBuffer sBuffer = new StringBuffer();
  Pattern p = Pattern.compile("[0-9]+.[0-9]*|[0-9]*.[0-9]+|[0-9]+");
  Matcher m = p.matcher(str);
  while (m.find()) {
    sBuffer.append(m.group());
  }
  return sBuffer.toString();

这是为了提取保留小数的数字

评论

0赞 OneCricketeer 3/18/2018
不处理底片
0赞 Moussa 12/23/2022
我认为应该转义这一点并处理负值,只需要添加"(-?[0-9]+\\.[0-9]*|-?[0-9]*\\.[0-9]+|-?[0-9]+)"-?
1赞 The_Fresher 5/27/2014 #5

我建议检查 ASCII 值以从字符串中提取数字 假设您有一个输入字符串作为 myname12345,如果您只想提取数字 12345,您可以通过先将 String 转换为字符数组,然后使用以下伪代码来实现

    for(int i=0; i < CharacterArray.length; i++)
    {
        if( a[i] >=48 && a[i] <= 58)
            System.out.print(a[i]);
    }

提取数字后,将它们附加到数组中

希望这会有所帮助

评论

0赞 Tom Blodget 5/27/2014
Java 字符串被计为 Unicode/UTF-16 代码单元的序列。根据 UTF-16 的设计,前 128 个字符的值与其 ASCII 编码相同(大小不同);除此之外,认为您正在处理 ASCII 会导致错误。
55赞 Maxim Shoustin 9/4/2014 #6

如何使用java.lang.String方法:replaceAll

    String str = "qwerty-1qwerty-2 455 f0gfg 4";      
    str = str.replaceAll("[^-?0-9]+", " "); 
    System.out.println(Arrays.asList(str.trim().split(" ")));

输出:

[-1, -2, 455, 0, 4]

描述

[^-?0-9]+
  • [并将一组字符分隔为单匹配,即以任何顺序仅匹配一次]
  • ^在集合的开头使用的特殊标识符,用于指示匹配分隔集中不存在的所有字符,而不是集合中存在的所有字符。
  • +在一次和无限次之间,尽可能多地回馈,根据需要回馈
  • -?字符“-”和“?”
  • 0-9介于“0”和“9”之间的字符

评论

6赞 Alan Moore 5/18/2016
为什么要保留问号?此外,它本身被视为一个数字,以及 、 和 等内容。-9----61-2-3
1赞 Jcc.Sanabria 2/3/2017
一个非常好的选择,无需使用导入库;)
8赞 Mugoma J. Okomba 4/7/2016 #7

接受的答案检测数字,但不检测格式化的数字,例如 2,000,也不检测小数,例如 4.8。对于这样的用途:-?\\d+(,\\d+)*?\\.?\\d+?

Pattern p = Pattern.compile("-?\\d+(,\\d+)*?\\.?\\d+?");
List<String> numbers = new ArrayList<String>();
Matcher m = p.matcher("Government has distributed 4.8 million textbooks to 2,000 schools");
while (m.find()) {  
    numbers.add(m.group());
}   
System.out.println(numbers);

输出:[4.8, 2,000]

评论

2赞 Alan Moore 5/18/2016
@JulienS.:我不同意。这个正则表达式的作用远远超出了 OP 的要求,而且它做得不正确。(至少,小数部分应该在一个可选组中,其中的所有内容都是必需的和贪婪的:。(?:\.\d+)?
0赞 Julien 5/20/2016
小数部分肯定有一点。但是,遇到格式化的数字是很常见的。
0赞 Mugoma J. Okomba 7/15/2016
@AlanMoore SO 的许多访问者正在寻找任何/不同的方法来解决具有不同相似性/差异性的问题,提出建议是有帮助的。甚至 OP 也可能过于简单化。
5赞 Bernhard Barker 12/31/2017 #8

使用 Java 8,您可以执行以下操作:

String str = "There 0 are 1 some -2-34 -numbers 567 here 890 .";
int[] ints = Arrays.stream(str.replaceAll("-", " -").split("[^-\\d]+"))
                 .filter(s -> !s.matches("-?"))
                 .mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890]

如果你没有负数,你可以去掉(并在 中使用),因为这只是为了正确拆分类似的东西(这也可以纯粹用正则表达式来处理,但它相当复杂)。replaceAll!s.isEmpty()filter2-34split

Arrays.stream将我们的 变成 Stream<String>String[]

filter删除前导和尾随空字符串以及任何不属于数字的空字符串。-

mapToInt(Integer::parseInt).toArray()呼吁每个人给我们一个.parseIntStringint[]


另外,Java 9 有一个 Matcher.results 方法,它应该允许如下内容:

Pattern p = Pattern.compile("-?\\d+");
Matcher m = p.matcher("There 0 are 1 some -2-34 -numbers 567 here 890 .");
int[] ints = m.results().map(MatchResults::group).mapToInt(Integer::parseInt).toArray();
System.out.println(Arrays.toString(ints)); // prints [0, 1, -2, -34, 567, 890]

就目前而言,这些都不是像其他答案中所示的那样,仅使用 / 循环遍历结果,但是如果您想使用更复杂的操作来跟进这一点,这应该更简单,这些操作通过使用流可以显着简化。PatternMatcher

0赞 user2902302 1/9/2018 #9

我发现这个表达最简单

String[] extractednums = msg.split("\\\\D++");
1赞 Shankara Narayana 9/11/2018 #10

使用它提取所有实数。

public static ArrayList<Double> extractNumbersInOrder(String str){

    str+='a';
    double[] returnArray = new double[]{};

    ArrayList<Double> list = new ArrayList<Double>();
    String singleNum="";
    Boolean numStarted;
    for(char c:str.toCharArray()){

        if(isNumber(c)){
            singleNum+=c;

        } else {
            if(!singleNum.equals("")){  //number ended
                list.add(Double.valueOf(singleNum));
                System.out.println(singleNum);
                singleNum="";
            }
        }
    }

    return list;
}


public static boolean isNumber(char c){
    if(Character.isDigit(c)||c=='-'||c=='+'||c=='.'){
        return true;
    } else {
        return false;
    }
}
1赞 AnDus 10/18/2018 #11

用于表示实数的分数和分组字符可能因语言而异。根据语言的不同,相同的实数可以以非常不同的方式书写。

德语中的200万数字

2,000,000.00

和英文

2.000.000,00

一种以与语言无关的方式从给定字符串中完全提取实数的方法:

public List<BigDecimal> extractDecimals(final String s, final char fraction, final char grouping) {
    List<BigDecimal> decimals = new ArrayList<BigDecimal>();
    //Remove grouping character for easier regexp extraction
    StringBuilder noGrouping = new StringBuilder();
    int i = 0;
    while(i >= 0 && i < s.length()) {
        char c = s.charAt(i);
        if(c == grouping) {
            int prev = i-1, next = i+1;
            boolean isValidGroupingChar =
                    prev >= 0 && Character.isDigit(s.charAt(prev)) &&
                    next < s.length() && Character.isDigit(s.charAt(next));                 
            if(!isValidGroupingChar)
                noGrouping.append(c);
            i++;
        } else {
            noGrouping.append(c);
            i++;
        }
    }
    //the '.' character has to be escaped in regular expressions
    String fractionRegex = fraction == POINT ? "\\." : String.valueOf(fraction);
    Pattern p = Pattern.compile("-?(\\d+" + fractionRegex + "\\d+|\\d+)");
    Matcher m = p.matcher(noGrouping);
    while (m.find()) {
        String match = m.group().replace(COMMA, POINT);
        decimals.add(new BigDecimal(match));
    }
    return decimals;
}
1赞 dxl 4/19/2019 #12

如果要排除单词中包含的数字(如 bar1 或 aa1bb),请将单词边界 \b 添加到任何基于正则表达式的答案中。例如:

Pattern p = Pattern.compile("\\b-?\\d+\\b");
Matcher m = p.matcher("9There 9are more9 th9an -2 and less than 12 numbers here9");
while (m.find()) {
  System.out.println(m.group());
}

显示:

2
12
0赞 user3509903 11/21/2019 #13
public static String extractNumberFromString(String number) {
    String num = number.replaceAll("[^0-9]+", " ");
    return num.replaceAll(" ", "");
}

仅从字符串中提取数字