将字母数字字符串转换为数字和字符串的映射时生成的空映射

时间:2018-05-08 09:27:15

标签: java regex string pattern-matching

以下代码片段用于将字母数字字符串分割为数字和字符串的映射,该映射将作为RestAPI的响应正文参数。

String alphaNumericStr = "1XXGTE_FUSION2XXBIR_STALIO3XXVTE_CORE";
String regex = "[^a-zA-Z0-9']+";
Matcher matcher = Pattern.compile(regex).matcher(alphaNumericStr);

Map<Integer, String> map = new HashMap<>();
while (matcher.find()) {
    map.put(Integer.parseInt(matcher.group(1)), matcher.group(2));
}
System.out.println(map);

预期结果是

{1=XXGTE_FUSION, 2=XXBIR_STALIO, 3=XXVTE_CORE}

但我得到一张空地图。任何人都可以帮我这个。

3 个答案:

答案 0 :(得分:3)

您的代码应该抛出java.lang.IndexOutOfBoundsException: No group 1,因为您尝试提取matcher.group(1)matcher.group(2),但您的正则表达式中没有任何一个。

相反,您可以使用此正则表达式:(\\d+)(\\D+)匹配两个组,第一个匹配一个或多个数字,第二个匹配一个或多个非数字。

String alphaNumericStr = "1XXGTE_FUSION2XXBIR_STALIO3XXVTE_CORE";
String regex = "(\\d+)(\\D+)";
Matcher matcher = Pattern.compile(regex).matcher(alphaNumericStr);

Map<Integer, String> map = new HashMap<>();
while (matcher.find()) {
    map.put(Integer.parseInt(matcher.group(1)), matcher.group(2));
}
System.out.println(map);    

如果您使用的是Java 9+,则可以使用:

Map<Integer, String> map = Pattern.compile(regex)
        .matcher(alphaNumericStr)
        .results()
        .collect(Collectors.toMap(
                m -> Integer.parseInt(m.group(1)), m -> m.group(2)
        ));

System.out.println(map);

输出

{1=XXGTE_FUSION, 2=XXBIR_STALIO, 3=XXVTE_CORE}

我笑着说你在这里阅读这篇文章:Divide an alphanumeric string into a map of numbers and strings

答案 1 :(得分:2)

问题在于正则表达式。您的正则表达式不包含任何组,并且您尝试提取它们。

只需将正则表达式更改为以下内容。

String regex = "(\\d)([a-zA-Z_]+)";

此处的第一个组(\\d)将匹配整数。第二组[a-zA-Z_]+将匹配由字母组合和_。

组合形成的任何字符序列
String alphaNumericStr = "1XXGTE_FUSION2XXBIR_STALIO3XXVTE_CORE";
String regex = "(\\d)([a-zA-Z_]+)";
Matcher matcher = Pattern.compile(regex).matcher(alphaNumericStr);

Map<Integer, String> map = new HashMap<>();

while (matcher.find()) {
    map.put(Integer.parseInt(matcher.group(1)), matcher.group(2));
}

System.out.println(map);

现在可以解决这个问题。

https://ideone.com/gZOhza

答案 2 :(得分:2)

作为替代方案,您可以使用两个拆分调用来实现相同的功能(完全避免使用正则表达式API):

String text = "1XXGTE_FUSION2XXBIR_STALIO3XXVTE_CORE";

String[] keys   = text.split("\\D+");
String[] values = text.split("\\d+");

Map<String, String> map = new HashMap<>();
for (int i = 0; i < keys.length; i++) {
    map.put(keys[i], values[i + 1]); // +1 to skip the first blank
}

System.out.println(map);

打印哪些:

{1=XXGTE_FUSION, 2=XXBIR_STALIO, 3=XXVTE_CORE}