說我有一個文件,其中包含一些文本。有「substr1」,「substr2」,「substr3」等子字符串。我需要用其他文本替換所有這些子字符串,如「repl1」,「repl2」,「repl3」。在Python中,我將創建一個這樣的解釋:立即替換多個子字符串
{
"substr1": "repl1",
"substr2": "repl2",
"substr3": "repl3"
}
和創建模式加入與鍵「|」,然後用re.sub
功能替代。 在Java中是否有類似的簡單方法?
說我有一個文件,其中包含一些文本。有「substr1」,「substr2」,「substr3」等子字符串。我需要用其他文本替換所有這些子字符串,如「repl1」,「repl2」,「repl3」。在Python中,我將創建一個這樣的解釋:立即替換多個子字符串
{
"substr1": "repl1",
"substr2": "repl2",
"substr3": "repl3"
}
和創建模式加入與鍵「|」,然後用re.sub
功能替代。 在Java中是否有類似的簡單方法?
這是你的Python-建議如何轉換爲Java:
Map<String, String> replacements = new HashMap<String, String>() {{
put("substr1", "repl1");
put("substr2", "repl2");
put("substr3", "repl3");
}};
String input = "lorem substr1 ipsum substr2 dolor substr3 amet";
// create the pattern joining the keys with '|'
String regexp = "substr1|substr2|substr3";
StringBuffer sb = new StringBuffer();
Pattern p = Pattern.compile(regexp);
Matcher m = p.matcher(input);
while (m.find())
m.appendReplacement(sb, replacements.get(m.group()));
m.appendTail(sb);
System.out.println(sb.toString()); // lorem repl1 ipsum repl2 dolor repl3 amet
這種方法做了simultanious(即 「一次」)替換。即,如果你碰巧有
"a" -> "b"
"b" -> "c"
那麼這種做法將給"a b" -> "b c"
,而不是答案建議你應該鏈多次打電話給replace
或replaceAll
這將使"c c"
。
(如果推廣這種方法以編程方式創建的正則表達式,請確保您Pattern.quote
每個單獨的搜索詞和Matcher.quoteReplacement
每個替換詞。)
return yourString.replaceAll("substr1","relp1").
replaceAll("substr2","relp2").
replaceAll("substr3","relp3")
-1。這不是全部,並且不必要地使用正則表達式方法(replaceAll)而不是普通的String方法(replace)。 – Boann
首先,問題的演示:
String s = "I have three cats and two dogs.";
s = s.replace("cats", "dogs")
.replace("dogs", "budgies");
System.out.println(s);
這是爲了取代貓=>狗和狗=> budgies,但順序替換操作的結果前一個r所以不幸的輸出是:
我有三budgies和兩budgies。
這是我的同步替換方法的實現。這很容易使用String.regionMatches
寫:
public static String simultaneousReplace(String subject, String... pairs) {
if (pairs.length % 2 != 0) throw new IllegalArgumentException(
"Strings to find and replace are not paired.");
StringBuilder sb = new StringBuilder();
int numPairs = pairs.length/2;
outer:
for (int i = 0; i < subject.length(); i++) {
for (int j = 0; j < numPairs; j++) {
String find = pairs[j * 2];
if (subject.regionMatches(i, find, 0, find.length())) {
sb.append(pairs[j * 2 + 1]);
i += find.length() - 1;
continue outer;
}
}
sb.append(subject.charAt(i));
}
return sb.toString();
}
測試:
String s = "I have three cats and two dogs.";
s = simultaneousReplace(s,
"cats", "dogs",
"dogs", "budgies");
System.out.println(s);
輸出:
我有三條狗和兩個虎皮鸚鵡。
此外,它在進行同步替換時有時很有用,以確保查找最長匹配。 (例如,PHP的strtr
函數執行此操作。)這是我的實現:
public static String simultaneousReplaceLongest(String subject, String... pairs) {
if (pairs.length % 2 != 0) throw new IllegalArgumentException(
"Strings to find and replace are not paired.");
StringBuilder sb = new StringBuilder();
int numPairs = pairs.length/2;
for (int i = 0; i < subject.length(); i++) {
int longestMatchIndex = -1;
int longestMatchLength = -1;
for (int j = 0; j < numPairs; j++) {
String find = pairs[j * 2];
if (subject.regionMatches(i, find, 0, find.length())) {
if (find.length() > longestMatchLength) {
longestMatchIndex = j;
longestMatchLength = find.length();
}
}
}
if (longestMatchIndex >= 0) {
sb.append(pairs[longestMatchIndex * 2 + 1]);
i += longestMatchLength - 1;
} else {
sb.append(subject.charAt(i));
}
}
return sb.toString();
}
爲什麼你需要這個?舉例如下:
String truth = "Java is to JavaScript";
truth += " as " + simultaneousReplaceLongest(truth,
"Java", "Ham",
"JavaScript", "Hamster");
System.out.println(truth);
輸出:
Java是對JavaScript作爲火腿是倉鼠
如果我們使用的simultaneousReplace
代替simultaneousReplaceLongest
,輸出將不得不 「HamScript」而不是「倉鼠」:)
請注意,上述方法是區分大小寫的。如果您需要不區分大小寫的版本,則可以輕鬆修改上述內容,因爲String.regionMatches
可以使用ignoreCase
參數。
相關主題 - http://stackoverflow.com/questions/2049528/java-best-way-for-string-find-and-replace – adatapost