如何从字符串中提取所有整数并将它们存储在 java 中的 int 数组中

How to extract all integers from a string and store them in an int array in java

我想获取一个字符串并隔离其中的所有整数,然后将它们存储在一个数组中。

输入的字符串永远只包含字母 a-z(大写和小写)、数字 0-9 和“-”(读作减号)。

到目前为止我已经写了:

String str = readString();

String[] arr = str.split("[^0-9-]+");

如果我的输入字符串例如是“15abc-59abc31abc100”,上面的代码可以正常工作,我只需要将字符串数组中的每个元素转换为 int,但是如果我的输入字符串在要分隔的数字之间没有字母他们将无法正常工作。示例:abc59-12abc56-10abc10 将生成一个只有 3 个元素的数组:59-12、56-10、10 如何让它将减号识别为数组中新元素的开始而不丢失符号本身?

理想情况下,我希望输入“abc59-12abc56-10abc10”在拆分后看起来像这样:

String[] arr = {"59","-12","56","-10","10");

读字符串();方法将始终提供我在上面描述的字符串类型 btw.

你在这里真正想要的是 - 一个有效的 'number symbol',但是 只有 任何给定数字块的开始。

但是,通过尝试匹配它们之间的负数 space,您给自己造成了困难:用正则表达式来表达这很棘手。

但是,如果你走的是积极的路线(写一个正则表达式来描述 一个数字),那将是微不足道的:Pattern.compile("-?\d+") 完美地描述了它:一个可选的减号后跟一位或多位数字。很简单。如果您的输入是“aa----5”,它甚至会 'work',它有一个匹配序列 (-5)。

所以..那么就这样做吧。你在这里滥用 split。不要滥用系统,一旦你把事情变得更复杂一点,它往往会变得很糟糕。

private static final Pattern NUMBER = Pattern.compile("-?\d+");

public List<Integer> getNumbers(String in) {
  Matcher m = NUMBER.matcher(in);
  var out = new ArrayList<Integer>();
  while (m.find()) out.add(Integer.parseInt(m.group(0)));
  return out;
}

这里使用了一些技巧:

  • m.find() 在输入字符串中查找与提供的正则表达式匹配的下一个子序列。
  • 正则表达式默认为 'greedy'。意思是,字符串“1234”可以通过多种方式进行同等合法的解释:那是单个项目 (1234) 吗?毕竟,Just the '1' 是否也匹配“-?\d+”。 “贪心”意味着正则表达式将匹配它们可以匹配的最长序列。毫无疑问,这正是您想要的。
  • m.group(0) 为您匹配。 0 是包含整个找到的序列的特殊组。如果你在正则表达式中使用括号,你就可以分组,你也可以得到它们,例如如果您想排除减号,您可以完成 "-?(\d+)" - 请注意括号。现在你可以做 m.group(1).
  • 请注意,如果您必须有一个 int[],则将整数列表转换为 int[] 需要一个循环。 toArray 做不到(Integer 不是 int,但是 List<int> 目前是非法的 java)。

这是一个单行代码:去除前导和尾随非数字,然后在 non-digit/minus 上拆分,转换为 int,然后收集到一个数组中:

int[] numbers = Arrays.stream(str.replaceAll("^\D+|\D+$", "").split("(?=-\d)|[^-\d]+"))
  .mapToInt(Integer::parseInt).toArray();

这里的关键是拆分,当后面的字符是减号然后是数字时,它会进行零宽度吐出, 在既不是减号也不是数字的字符上。