【问题标题】:Replace characters in string, but only after a certain point in the string替换字符串中的字符,但仅在字符串中的某个点之后
【发布时间】:2018-06-30 09:35:52
【问题描述】:

我从一个列表中创建了一个巨大的字符串,我想用一个新行替换每个“,”,但只能在某个以“http”开头的字符串之后。我使用的是.replace(",","\n"),但这会替换每个人,所以我需要一种像这样的while循环

i = str.indexOf(',');
while(i >= 0) {
  System.out.println(i);
  i = str.indexOf(',', i+1);
} 

那么我可能需要创建子字符串并在替换之前检查它是否有 http,我不是专家,我相信有更简单的方法。

【问题讨论】:

  • 可能是str = str.replaceAll("(http[^,]*),","$1\n")?
  • 先提取相关部分。因此搜索您的http 字符串并在那里拆分,例如使用String#substringString#indexOf。之后使用常规的replaceAll 方法。
  • @Zabuza that won't work 我最终会得到相同的结果,想象一个字符串“嗨,你好,你好吗,http//myurl.com,再见,很高兴见到你, http//otherurl.com , ” 我只希望它替换 http 之后的 2 个逗号
  • @WiktorStribiżew 我一定会试试这个非常感谢,我会尽快发表评论
  • 如何处理原始列表而不是先创建“巨大的字符串”?

标签: java regex string replace


【解决方案1】:

所以要实现我之前关于处理原始列表而不是先创建巨大字符串的评论。

static final Pattern PATTERN = Pattern.compile("(.*http)(.*)");

public static <T> String toHugeStringReplacingCommas(List<T> list, Function<T, String> convertToString) {
    // we're collecting a lot of Strings, a StringBuilder is most efficient
    StringBuilder builder = new StringBuilder();
    for (T item : list) {
        String string = convertToString(item);
        Matcher m = PATTERN.matcher(string);
        if (m.isMatch(string)) {
            // everything up to and including "http"
            StringBuilder replaced = new StringBuilder(m.groups(1));
            replaced.append(m.groups(2).replaceAll(",", "\n"));
            string = replaced.toString();
        }
        builder.append(string);
    }
    return builder.toString();
}

这将在您构建“巨大的字符串”时进行替换,因此它应该更有效率。但是,它确实要求每个项目中都存在“http”才能替换其余项目;如果它总体上只发生一次,您需要跟踪它是否在更早的时间发生,如下所示:

public static <T> String toHugeStringReplacingCommas(List<T> list, Function<T, String> convertToString) {
    StringBuilder builder = new StringBuilder();
    boolean httpFound = false;
    for (T item : list) {
        String string = convertToString(item);
        if (!httpFound) {
            Matcher m = PATTERN.matcher(string);
            httpFound = m.isMatch(string);
            if (httpFound) {
                // we found the first occurance of "http"
                // append the part up to http without replacing,
                // leave the replacing of the rest to be done outside the loop
                builder.append(m.groups(1));
                string = m.groups(2);
            }
        }
        if (httpFound) {
            string = string.replaceAll(",", "\n");
        }
        builder.append(string);
    }
    return builder.toString();
}

如果您正在构建的 List 包含以字符串开头的字符串,则可以将 TconvertToString 的东西放在一边,然后做

public static String toHugeStringReplacingCommas(List<String> list) {
    StringBuilder builder = new StringBuilder();
    for (String string : list) {
        // and so on

【讨论】:

    【解决方案2】:
        String inputStr = "aa.com,bb.com,http://cc.com,b,c,d";
        int httpIndex = inputStr.indexOf("http");
        String result = inputStr.substring(0,httpIndex) + inputStr.substring(httpIndex).replaceAll(",", "\n");
        System.out.println("result = " + result);
    

    结果:

    aa.com,bb.com,http://cc.com
    b
    c
    d

    【讨论】:

    • 有效。但是,似乎 OP 输入可以有多个 http 出现,并且它应该只替换出现之间的部分中的东西(参见 cmets)。所以 split 然后奇数索引或多个 indexOf 调用应该这样做。
    【解决方案3】:
    String s = "http://side.de/servet/patth?jjjj,qwe,rtz,zui,opl";
    
    if ( s.startsWith("http")) {
    
        s = s.replaceAll(",", "\n");
        System.out.println(s);;
    }
    

    然后输出

    http://side.de/servet/patth?jjjj
    qwe
    rtz
    zui
    opl
    

    【讨论】:

    • 你应该改用s.startsWith
    • 是的,使用 startWith 会更好。我改进了我的答案
    【解决方案4】:

    这应该可以解决问题。小心读取数据的方式。如果逐行读取,则将正确满足 http 检查。否则它将是一个长字符串,并且每个“,”都将被替换。如果您想阅读与示例格式相同的文本。搜索“http”字符串,然后从该索引创建一个子字符串。然后运行下面的 if 语句。

    if (s.contains("http")) {
        s = s.replace(",", "\n");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 2020-02-14
      • 2016-08-04
      • 2017-06-25
      • 2018-08-25
      • 2023-04-05
      相关资源
      最近更新 更多