Java有replace()和replaceAll()方法,用给定的新模式替换字符串的部分/序列。该功能的内部如何工作?如果我必须编写一个输入字符串,OldPattern,NewPattern的函数并用NewPattern 递归替换每一次出现的OldPattern而不使用RegEx,该怎么办? 我已经使用迭代为String输入完成了以下代码,它似乎工作。如果输入是characterArray而不是字符串怎么办?
public String replaceOld(String aInput, String aOldPattern, String aNewPattern)
{
if ( aOldPattern.equals("") ) {
throw new IllegalArgumentException("Old pattern must have content.");
}
final StringBuffer result = new StringBuffer();
int startIdx = 0;
int idxOld = 0;
while ((idxOld = aInput.indexOf(aOldPattern, startIdx)) >= 0) {
result.append( aInput.substring(startIdx, idxOld) );
result.append( aNewPattern );
//reset the startIdx to just after the current match, to see
//if there are any further matches
startIdx = idxOld + aOldPattern.length();
}
//the final chunk will go to the end of aInput
result.append( aInput.substring(startIdx) );
return result.toString();
}
答案 0 :(得分:4)
Java有replace()和replaceAll()方法,用给定的新模式替换字符串的部分/序列。
确切地说,这些方法创建了新的字符串,并替换了相关的字符。 Java String是不可变的。
该功能的内部如何运作?
这太复杂了,不能在这里详细解释。 (实际上细节可能因实施而异)。您最好的选择是自己阅读相关库类的源代码。 (源代码作为JDK的一部分进行分发,您的Java IDE应该能够向您展示。或者,Google搜索将在网上为您找到它。)
如果我必须编写一个输入字符串,OldPattern,NewPattern的函数,并且在不使用RegEx的情况下递归地将NewPattern的每一次出现替换为NewPattern,该怎么办?
好吧,如果你正在谈论在不使用Pattern
类的情况下进行模式匹配/替换,那么是的将变得棘手......更不用说它毫无意义了。
(递归解决方案可能很危险。考虑这个问题:“递归地用”a“中的”ba“替换所有”a“实例。结果应该是什么?你是否应该尝试这样做?)< / p>
假设参数是简单的字符串(不是你描述的模式),那么这是一个递归的解决方案(未经测试):
public String replace1(String in, String target, String replacement) {
if (target.isEmpty()) {
return in;
}
int pos = in.indexOf(target);
if (pos < 0) {
return in;
}
String updated = in.substring(0, pos) + replacement +
in.substring(pos + target.length());
return replace1(updated, target, replacement);
}
解决 1 问题的版本,你希望替换是递归的;即您要替换替换过程插入的target
实例的位置。如果您不想这样做,那么:
public String replace2(String in, String target, String replacement) {
if (target.isEmpty()) {
return in;
}
int pos = in.indexOf(target);
if (pos < 0) {
return in;
}
return in.substring(0, pos) + replacement +
replace2(in.substring(pos + target.length()),
target, replacement);
}
请注意,与原始迭代解决方案相比,这些更少效率更高。甚至忽略所有正在进行的字符串复制。 Java不进行尾调用优化。
1 - 如果使用病态参数调用replace1
,则会出现堆栈溢出。例如replace1("ab", "b", "b")
答案 1 :(得分:1)
试
public static String replaceOld(String aInput, String aOldPattern, String aNewPattern, int i) {
i = aInput.indexOf(aOldPattern, i);
if (i == -1) {
return aInput;
}
aInput = aInput.substring(0, i) + aNewPattern + aInput.substring(i + aOldPattern.length());
return replaceOld(aInput, aOldPattern, aNewPattern, i + aNewPattern.length());
}
请注意,param i
用于优化,因此indexOf不会每次都从pos 0进行扫描。它还解决了“在”a“问题中递归替换”a“与”ba“的所有实例。
答案 2 :(得分:0)
也许这种方法会回答你的问题。
static int indexOf(char[] string, char[] pattern, int startIndex) {
int index = startIndex;
while(true) {
while(index < string.length && string[index] != pattern[0]) index++;
if(index >= string.length || index+pattern.length > string.length) return -1;
boolean match = true;
for(int i = 1; i < pattern.length; i++) {
if(string[index+i] != pattern[i]) {
match = false;
break;
}
}
if(match) return index;
else index += 1;
}
}
如果您需要递归替换方法,请使用此
static String replace(String string, String pattern, String replacement) {
int index = string.indexOf(pattern);
if(index < 0) return string;
int endIndex = index+pattern.length();
return string.substring(0, index) + replacement +
replace(string.substring(endIndex), pattern, replacement);
}