【问题标题】:Java: replace a set of characters with other different charactersJava:用其他不同的字符替换一组字符
【发布时间】:2014-06-04 04:40:26
【问题描述】:

我应该制作一个自定义装饰器,这样我就可以在控制台和文件中的输入中进行替换:

  1. 一组具有特定字符的字符(例如char[] x = {'a', 'b'}char y = '*',所以ab 都变成*
  2. 一组字符与另一组配对字符(例如char[] x = {'a', 'b'}char[] y = {'c', 'd'},所以a 变为cb 变为d

最好的方法是什么?我用正则表达式(String replaceAll = s.replaceAll("(a|b)", String.valueOf(replacement));)制作了第一个,但这不适用于第二种情况。有没有办法在一个正则表达式中制作第二种情况?我应该做一个 HashMap 吗?

【问题讨论】:

    标签: java regex char


    【解决方案1】:

    首先在替换字符和它的替换字符之间创建某种映射会更容易。我的意思是像

    Map<String, String> map = new HashMap<>();
    map.put("a", "c");
    map.put("b", "d");
    

    那么您可以使用 Matcher 类中的 appendReplacementappendTail 来替换匹配的字符。可以像map.get(matchedCharacter) 一样决定如何获取替换字符。

    简单演示

    Map<String, String> map = new HashMap<>();
    map.put("a", "c");
    map.put("b", "d");
    
    String demo = "abcdef";
    
    Pattern p = Pattern.compile("[ab]");
    Matcher m = p.matcher(demo);
    
    StringBuffer sb = new StringBuffer();
    while (m.find()){
        m.appendReplacement(sb, map.get(m.group()));
    }
    m.appendTail(sb);
    String replaced = sb.toString();
    
    System.out.println(replaced);
    

    输出:cdcdef


    Java 9 及更高版本更新

    在下面的模板中,我们通常只更改一件事,即决定使用什么来替换已建立的匹配。

    StringBuffer sb = new StringBuffer();
    while (m.find()){
        m.appendReplacement(sb, /* decision about replacement*/ );
        //                         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    }
    m.appendTail(sb);
    String replaced = sb.toString();
    

    因此,由于该逻辑的其余部分是重复的,因此该模板被包装为String replaceAll​(Function&lt;MatchResult,String&gt; replacer),这要求我们提供获取已建立匹配替换的逻辑。所以上面的代码可以简化为:

    Map<String, String> map = new HashMap<>();
    map.put("a", "c");
    map.put("b", "d");
    
    String demo = "abcdef";
    
    Pattern p = Pattern.compile("[ab]");
    Matcher m = p.matcher(demo);
    
    String replaced = m.replaceAll(match -> map.get(match.group()));
    System.out.println(replaced);
    

    【讨论】:

      【解决方案2】:

      还有一种更快的方法:

      public static void main(String[] args) {
          String target      = "ab";
          String replacement = "**";
      
          char[] array = "abcde".toCharArray();
          for (int i = 0; i < array.length; i++) {
              int index = target.indexOf(array[i]);
              if (index != -1) {
                  array[i] = replacement.charAt(index);
              }
          }
      
          System.out.println(array);
      }
      

      【讨论】:

        【解决方案3】:

        在这里,对于任何示例,这项工作 100% 正确....

        public static void main(String[] args) {
                String test = "My name is Baba";
        
                Character[] x = { 'a', 'b' };
        
                StringBuilder sb = new StringBuilder();
                sb.append("(");
                for (int i = 0; i < x.length; i++) {
                    if (i == (x.length - 1)) {
                        sb.append(x[i] + ")");
                    } else {
                        sb.append(x[i] + "|");
                    }
                }
        
                System.out.println(sb.toString());
        
                Character y = 'c';
                Character[] y1 = { 'd', 'e' };
        
                if (y.getClass().isArray()) {
                    for (int i = 0; i < y1.length; i++) {
                        test = test.replaceAll(x[i].toString(), y1[i].toString());
                    }
                } else {
                    test = test.replaceAll(sb.toString(), String.valueOf(y.toString()));
                }
        
                System.out.println(test);
            }
        

        【讨论】:

        • 看起来不错且简单的解决方案。尽管我已经选择了@Pashemo 的答案并实施了它,但我会为你的努力加分。谢谢!
        【解决方案4】:

        DJ麦克,

        对于第二个,在替换过程中会有所帮助的是调用一个方法,您可以在该方法中注入逻辑以用不同的字符串替换不同的字符。

        PHP 有一个很好的工具来做这件事,叫做 preg_replace_callback()。链接的答案是关于Java equivalent of preg_replace_callback()的问题

        【讨论】:

        • 我一直在寻找相同的 preg_replace_callback() 风格的实现,因为我非常了解 PHP,但此时这似乎太复杂了,我还实现了我标记为答案的解决方案。无论如何,谢谢你的努力。我会更喜欢正则表达式样式,但现在就是这样。很高兴知道未来。
        • 哈,我们在同一条轨道上。很高兴你找到了一个解决方案 DJ,祝你周末愉快。 :)
        猜你喜欢
        • 1970-01-01
        • 2017-11-06
        • 2017-12-17
        • 1970-01-01
        • 2011-03-30
        • 1970-01-01
        • 2022-06-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多