【问题标题】:Replace only strings that are not substrings of similar strings?仅替换不是相似字符串的子字符串的字符串?
【发布时间】:2017-06-21 21:24:41
【问题描述】:

我有一个字符串12999986, 31999999, 39949283, 99002999,我试图用00 模式替换所有模式99。但是,该模式不能是另一个类似字符串的子字符串的一部分,例如9999999。在此示例中,输出将是 12999986, 31999999, 30049283, 0000299939949283300492839900299900002999)。我已经创建了这个方法,但它实际上不适用于较大的字符串(找不到所有模式,在随机位置插入字符串):

public static String replaceAllExact(String data, String searchString, String replacement) {
    List<Integer> locations = new ArrayList<>(); //start (exclusive)
    char[] dataChars = data.toCharArray();
    char[] searchStringChars = searchString.toCharArray();
    char[] replacementChars = replacement.toCharArray();

    int i = 0;
    int k = 0;
    int startIndex = 0; 
    int searchStringCharsLength = searchStringChars.length - 1;

    for(char c : dataChars) {
        if(c != searchStringChars[i] && i == 0) { //not the start of a pattern; continue
            k++;
            continue;
        }else if(c == searchStringChars[i] && i == 0) { //might be the pattern we're looking for
            startIndex = k;
            i++;
        }else if((c == searchStringChars[i] && i > searchStringCharsLength) || ((c != searchStringChars[i] && i < searchStringCharsLength) && i != 0)) { //pattern was too long or too short to be the pattern we're looking for
            i = 0;
        }else if(c == searchStringChars[i] && i < searchStringCharsLength) { //could be the pattern... keep going
            i++;
        }else if(c != searchStringChars[i] && i != 0 && i == searchStringCharsLength) { //this is the pattern we're looking for
            locations.add(startIndex);
            i = 0;
        }

        k++;
    }

    int offset = 0;
    StringBuilder builder = new StringBuilder(data);

    for(int l : locations) {
        l += offset;
        builder.delete(l, l + searchString.length());
        builder.insert(l, replacementChars);
        offset = (builder.length() - data.length());
    }

    return builder.toString();
}

我怎样才能做到这一点?如果可能的话,欢迎使用正则表达式解决方案。

澄清

类似的字符串是一个普通替换将替换其中一些字符的字符串。例如,使用标准库replace(CharSequence target, CharSequence replacement),字符串31999999 会被认为是相似的,因为replace(99, 00) 可以替换一些字符。

字符串39349283 不是类似的字符串,因为replace(99, 00) 不能替换任何字符。字符串39949283 类似,因为replace(99, 00) 可以替换一些字符。

【问题讨论】:

  • 您能进一步解释一下吗?我现在读它的方式听起来你想替换字符串中的子字符串,而你的子字符串不包含在字符串的另一个子字符串中,这意味着它永远不会被替换——因为子字符串几乎总是会成为一部分给定大小允许的较大子字符串。它只是像您的示例中那样重复字符吗?
  • 我想我的问题是——什么是相似的字符串?
  • @EastonBornmeier 两个连续的 9 被两个连续的 0 替换,但如果连续两个以上,他不希望它们被替换。
  • @PatrickRoberts 但这应该也处理“99”以外的不同模式吗?说...“37”的类似字符串是什么?
  • 所以按照这个逻辑,我会说“999”不是一个类似的字符串,因为它不仅仅是前一个字符串的重复。那有意义吗?这个定义对于解决这个问题非常重要,所以我想确保我理解

标签: java string replace substring


【解决方案1】:

如果我理解正确,您想用其他东西替换 99,但前提是它之前或之后没有 9

在这种情况下,您可以使用look-around 机制并确保

  • 之前没有9,通过(?&lt;!9)
  • 之后没有9,通过(?!9)

所以你可以使用str = str.replaceAll("(?&lt;!9)99(?!9)", "00")

【讨论】:

  • 我不认为这个问题是针对 99 的,而是一个普遍的模式。
  • @Noobgineer 同意,但可以轻松更改解决方案以用于其他情况。真正的解决方案取决于 OP 真正想要实现的目标。
  • @Noobgineer 在这种情况下,您可以相应地调整正则表达式模式。
  • 除非 OP 使用像示例中那样的重复模式,我认为这在很大程度上取决于“模式”的实际问题规范是什么以及它被替换时的参数构成
猜你喜欢
  • 2014-06-09
  • 1970-01-01
  • 2012-04-03
  • 2013-07-23
  • 1970-01-01
  • 2017-04-24
相关资源
最近更新 更多