如何在不创建更多字符串对象的情况下一次用替换方法替换多个字符串



我得到了一个字符串测试"{"userName": "<userName>","firstName": "<firstName>","lastName": "<lastName>"}"。 我想要的是我想用动态值替换尖括号中的内容。示例代码:

public class Test {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String toBeReplaced0 = "alpha";
        String toBeReplaced1 = "beta";
        String toBeReplaced2 = "gama";
        String test = "{"userName": "<userName>","firstName": "<firstName>","lastName": "<lastName>"}";
    }
}

现在在这个代码中,我想一次用alpha<firstName> beta<lastName> gama替换<userName>,而不创建多个字符串对象。这不是一个家庭作业问题。 test字符串中可以包含更多角度元素,以填充动态值。我如何使用替换方法或其他任何方法执行此操作。.

Matcher.appendReplacement可能是一个选项。例:

public static void main(String[] args){
    String toBeReplaced0 = "alpha";
    String toBeReplaced1 = "beta";
    String toBeReplaced2 = "gama";
    String test = "{"userName": "<userName>","firstName": "<firstName>","lastName": "<lastName>"}";
    System.out.println(findAndReplace(test,toBeReplaced0,toBeReplaced1,toBeReplaced2));        
}
public static String findAndReplace(String original, String... replacments){
    Pattern p = Pattern.compile("<[^<]*>");
    Matcher m1 = p.matcher(original);
    // count the matches
    int count = 0;
    while (m1.find()){
        count++; 
    }
    // if matches count equals replacement params length replace in the given order
    if(count == replacments.length){
        Matcher m = p.matcher(original);
        StringBuffer sb = new StringBuffer();
        int i = 0;
        while (m.find()) {
            m.appendReplacement(sb, replacments[i]);
            i++;
        }
        m.appendTail(sb);            
        return sb.toString();
    }
    //else return original
    return original;
}

如果这是 JSON,我更喜欢使用 JSON 库来动态构造生成的字符串并减轻任何可能的语法错误。

如果您真的想使用String.replaceAll()或类似的东西,我不希望这在上述有限的范围内成为问题。只需将您的呼叫链接在一起(例如,请参阅本教程)

请注意,字符串是不可变的,因此,如果不创建新的字符串对象,就无法轻松执行此操作。如果这真的是一个问题,也许你需要修改一个字符数组(但在替换多个不同长度的字符串时,这将是一项不平凡的任务,这些字符串不同于它们的占位符)。

只是:

String result = orig.replace("<userName>", "replacement");

(不要忘记字符串是不可变的,因此您必须使用此调用返回的结果)

我会用StringTemplate库来做到这一点。使用您的示例开箱即用:

    <dependency>
        <groupId>org.antlr</groupId>
        <artifactId>ST4</artifactId>
        <version>4.0.8</version>
        <scope>compile</scope>
    </dependency>
    // Given
    final ST template = new ST("{"userName": "<userName>","firstName": "<firstName>","lastName": "<lastName>"}");
    template.add("userName", "alpha");
    template.add("firstName", "beta");
    template.add("lastName", "gamma");
    // When
    final String result = template.render();
    // Then
    Assert.assertEquals("{"userName": "alpha","firstName": "beta","lastName": "gamma"}", result);

最新更新