【问题标题】:Java: Easiest way to replace strings with random stringsJava:用随机字符串替换字符串的最简单方法
【发布时间】:2008-10-25 21:39:59
【问题描述】:

字符串将由某些符号(例如ax、bx、dx、c、acc)和数字组成。

例如: 斧头 5 5 dx 3 加速 c ax bx

我想用同组的另一个符号(随机)替换一个或所有符号。即,将 {ax,bx,dx,c,acc} 之一替换为 {ax,bx,dx,c,acc} 之一。

替换示例: 符合 5 5 dx 3 加速 c ax bx 或者 5 5 dx 3 加速 斧头斧头

有没有办法用正则表达式做到这一点?在 Java 中?如果是,我应该使用哪些方法?

【问题讨论】:

    标签: java regex replace


    【解决方案1】:

    我认为这是从包含它们的超集的字符串中替换特定符号集的最干净的解决方案。 appendreplacement 是这个方法的关键。 一个重要的警告:不要在元素列表中包含任何未转义的美元字符 ($)。使用 "\$" 转义它们 最终使用
    .replaceall("\$","\\$"); 在将每个字符串添加到列表之前。 另请参阅对 $ 符号有疑问的 javadoc

    import java.util.*;
    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    
    public class ReplaceTokens {
    public static void main(String[] args) {
        List<String> elements = Arrays.asList("ax", "bx", "dx", "c", "acc");
        final String patternStr = join(elements, "|"); //build string "ax|bx|dx|c|acc" 
        Pattern p = Pattern.compile(patternStr);
        Matcher m = p.matcher("ax 5 5 dx 3 acc c ax bx");
        StringBuffer sb = new StringBuffer();
        Random rand = new Random();
        while (m.find()){
            String randomSymbol = elements.get(rand.nextInt(elements.size()));
            m.appendReplacement(sb,randomSymbol);
        }
        m.appendTail(sb);
        System.out.println(sb);
    }
    
    /**
     * this method is only needed to generate the string ax|bx|dx|c|acc in a clean way....
     * @see org.apache.commons.lang.StringUtils.join    for a more common alternative...
     */
    public static String join(List<String> s, String delimiter) {
        if (s.isEmpty()) return "";
        Iterator<String> iter = s.iterator();
        StringBuffer buffer = new StringBuffer(iter.next());
        while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
        return buffer.toString();
    }
    

    【讨论】:

      【解决方案2】:

      回答第一个问题:没有。

      由于您正在执行随机替换,正则表达式不会帮助您,正则表达式没有什么是随机的。 * 由于您的字符串在一个数组中,因此您不需要使用任何模式匹配来查找它们,因此再次不需要正则表达式。

      **编辑:问题已被编辑,因此不再说字符串在数组中。在这种情况下,假设它们都在一个大字符串中,您可能会构建一个正则表达式来查找要替换的部分,如其他答案所示。*

      【讨论】:

        【解决方案3】:
        1. 是的,这可以通过正则表达式来完成。 可能不是很漂亮,不是 没有一两个循环
        2. 是的,这可以用 Java 实现。
        3. 参见Randomregex
        4. 实施留给学生作为练习。

        【讨论】:

          【解决方案4】:

          使用Random 类生成一个随机整数来选择符号的索引。

              String text = "ax 5 5 dx 3 acc c ax bx";
              System.out.println("Original: " + text);
              String[] tokens = text.split(" ");
              List<Integer> symbols = new ArrayList<Integer>();
              for(int i=0; i<tokens.length; i++) {
                  try {
                      Integer.parseInt(tokens[i]);
                  } catch (Exception e) {
                      symbols.add(i);
                  }
              }
              Random rand = new Random();
              // this is the part you can do multiple times
              int source = symbols.get((rand.nextInt(symbols.size())));
              int target = symbols.get((rand.nextInt(symbols.size())));
              tokens[target] = tokens[source];
          
              String result = tokens[0];
              for(int i=1; i<tokens.length; i++) {
                  result = result + " " + tokens[i];
              }
              System.out.println("Result: " + result);
          

          在您join 将令牌重新组合在一起之前根据需要进行尽可能多的替换。

          这里有两个部分可能看起来很棘手。首先,try catch 来识别那些不是整数的标记。我建议您将该部分提取到它自己的方法中,因为它可以工作,但它有点 hacky。

          第二个是我设置sourcetarget 变量的地方。我在那里做的是随机选择一个非数字符号的 index。一旦我有两个随机索引,我可以在下一行交换它们。

          另一种方法是,在将原始字符串拆分为数组后,从随机选择的符号中构建一个新字符串。

          【讨论】:

            【解决方案5】:

            感谢一群人。这就是我想出的。看看你能不能想出一个更有效的方法。

            private final String[] symbolsPossible = {"ax","bx","cx","dx","foo"};
            private boolean exists;
            private final String mutate(String s)
            {
            String[] tokens=s.split(" ");
            for(int j=0; j<tokens.length; j++)
            if(Math.random()<.1) //10% chance of mutation per token
            {
            //checking to see if the token is a supported symbol
            exists=false;
            for(int i=0; i<symbolsPossible.length; i++)
                if(tokens[j].equals(symbolsPossible[i]))
                   exists=true;
            if(exists)
                tokens[j]=symbolsPossible[(int)Math.random()*symbolsPossible.length];
            }
            StringBuffer result=new StringBuffer();
            for(String t:tokens)
                result.append(t);
            return result;
            }
            

            【讨论】:

              猜你喜欢
              • 2011-01-24
              • 1970-01-01
              • 2017-05-20
              • 1970-01-01
              • 1970-01-01
              • 2010-09-18
              • 2017-03-08
              • 2021-05-29
              • 2012-05-29
              相关资源
              最近更新 更多