Java:使用对应的ID替换给定String上的数字

时间:2017-05-09 11:04:45

标签: java string hashmap substitution

我'我有一个像这样的字符串:

" [1],[2,4],[1,2,3],[12,42] ..."具有不可预测的结构(即可能有更多的括号或更多的数字)。

数字对应于HashMap中包含的某个ID。 例如:

1→Apollo11​​

2→NewYork12

4-> Hello3

...

42-> Joe4

...

如何用相应的id替换字符串中的数字,而不会产生歧义? 例如,如果我用数字代替数字,我可以:

取代1->甚至属于12的1也会受到影响。

如果我从最大的数字开始,即42,当4被替换时,即使是" 4"在Joe4中会受到影响。

感谢您的关注。

2 个答案:

答案 0 :(得分:0)

简单地用相关名称替换数字的出现会有一些缺点,因为您已经发现:

  • 你需要多次通过,如果你的字符串很大或你有大量的对,那么这可能意味着一个重大的性能损失
  • 如果你要将数字从大到小替换,你仍然会遇到问题,例如你只有4的映射,因此你仍然会替换42中的4
  • 使用正则表达式,您可以匹配不被字符或其他数字包围的数字,但这可能会进一步提高性能,但仍然有些脆弱,例如如果您用Apollo 11替换1,稍后替换11

因此,最安全的方法可能是将字符串拆分为数字,迭代标记,替换任何数字并重新连接元素。

示例:

Map<String, String> mapping = ...;
String input = "[1] ,[2,4], [1,2,3] ,[12,42]";
String[] elements = input.split("(?<=\\d++|\\D++)");
StringBuilder result = new StringBuilder();
for( String element : elements ) {
  //simple way to get around checking whether an element is a number: 
  //if there is nothing mapped, use the element itself - this also keeps unmapped numbers
  String replacement = mapping.get( element );
  result.appdend( replacement != null ? replacement : element );
}

正则表达式上的一些词曾经分裂过:

  • (?<=...)后面是零宽度外观,即它匹配...表达式的任何匹配之前的任何位置。
  • \d++|\D++匹配具有可能量词的任何数字或非数字序列(即尽可能匹配并且不会&#34;#34;返回&#34;匹配)。

整个表达式与您的数字之前的位置匹配,并且恰好在任何不是数字的位置之前(或换句话说:在您的数字之后)。

答案 1 :(得分:0)

这是我的解决方案(没有打磨,但我希望你能得到这个想法)。由于缺少查找值,我只需将所有值替换为**value**作为示例:

public static void main(String[] args) {
    String input = "[1] ,[2,4], [1,2,3] ,[12,42]...";
    int start = -1;
    StringBuilder builder = new StringBuilder();
    for (int idx = 0; idx < input.length(); idx++) {
        char c = input.charAt(idx);
        if (start == -1) {
            if (Character.isDigit(c)) {
                start = idx;
            } else {
                builder.append(c);
            }
        } else if (!Character.isDigit(c)) {
            builder.append(valueOf(input.substring(start, idx)) + c);
            start = -1;
        }
    }
    if (start != -1) {
        builder.append(valueOf(input.substring(start, input.length())));
    }
    System.out.println(builder);
}

private static String valueOf(String num) {
    int val = Integer.parseInt(num);
    return map.getOrDefault(val,"**" + val + "**");
}

<强>输出:

[**1**] ,[**2**,**4**], [**1**,**2**,**3**] ,[**12**,**42**]...

您必须将表达式map.getOrDefault(val,"**" + val + "**")替换为包含替换字符串的地图的引用。