Java中的多个同时子串替换

cs9*_*s95 11 java string stringbuilder

(我来自蟒蛇世界,所以我道歉,如果我使用的标准中的一些术语与常规.)

我有String一个List开始/结束索引来代替.没有太多细节,请考虑这个基本的模型:

String text = "my email is foo@bar.com and my number is (213)-XXX-XXXX"
List<Token> findings = SomeModule.someFnc(text);
Run Code Online (Sandbox Code Playgroud)

Token有定义

class Token {
    int start, end;
    String type;
}
Run Code Online (Sandbox Code Playgroud)

List表示我正在尝试编辑的敏感数据的开始和结束位置.

实际上,API返回我迭代的数据以获得:

[{ "start" : 12, "end" : 22, "type" : "EMAIL_ADDRESS" }, { "start" : 41, "end" : 54, "type" : "PHONE_NUMBER" }]
Run Code Online (Sandbox Code Playgroud)

使用这些数据,我的最终目标是编辑text这些Token对象指定的标记,以获得:

"my email is [EMAIL_ADDRESS] and my number is [PHONE_NUMBER]"
Run Code Online (Sandbox Code Playgroud)

使这个问题变得非常重要的是,替换子串的长度并不总是与它们所替换的子串相同.

我目前的行动计划是构建一个StringBuilderfrom text,按照起始索引的相反顺序对这些ID进行排序,然后从缓冲区的右端进行替换.

但有些东西告诉我应该有更好的方法......有吗?

Rob*_*sen 9

这种方法有效:

import java.util.ArrayList;
import java.util.List;

public class Test {
    public static void main(String[] args) {
        String text = "my email is foo@bar.com and my number is (213)-XXX-XXXX";

        List<Token> findings = new ArrayList<>();
        findings.add(new Token(12, 22, "EMAIL_ADDRESS"));
        findings.add(new Token(41, 54, "PHONE_NUMBER"));

        System.out.println(replace(text, findings));
    }

    public static String replace(String text, List<Token> findings) {
        int position = 0;
        StringBuilder result = new StringBuilder();

        for (Token finding : findings) {
            result.append(text.substring(position, finding.start));
            result.append('[').append(finding.type).append(']');

            position = finding.end + 1;
        }

        return result.append(text.substring(position)).toString();
    }
}

class Token {
    int start, end;
    String type;

    Token(int start, int end, String type) {
        this.start = start;
        this.end = end;
        this.type = type;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

my email is [EMAIL_ADDRESS] and my number is [PHONE_NUMBER]
Run Code Online (Sandbox Code Playgroud)

  • 哦那里可能有更优雅的解决方案.我会多考虑一下. (2认同)
  • 我会预先分配缓冲区,如`new StringBuilder(text.length()+ 32)`.否则,这是最快的解决方案(在Java中,目标是最小化对象创建). (2认同)