Java字符串查找和替换的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2049528/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java best way for string find and replace?
提问by vaske
I'm looking for the best approach for string find and replace in Java.
我正在寻找在 Java 中查找和替换字符串的最佳方法。
This is a sentence: "My name is Milan, people know me as Milan Vasic".
这是一句话:“我叫米兰,人们都知道我是米兰瓦西奇”。
I want to replace the string Milan with Milan Vasic, but on place where I have already Milan Vasic, that shouldn't be a case.
我想用 Milan Vasic 替换字符串 Milan,但在我已经有了 Milan Vasic 的地方,这不应该是一个案例。
after search/replace result should be: "My name is Milan Vasic, people know me as Milan Vasic".
搜索/替换后的结果应该是:“我的名字是米兰瓦西克,人们都知道我是米兰瓦西克”。
I was try to use indexOf() and also Pattern/Matcher combination, but neither of my results not looks elegant, does someone have elegant solution?
我尝试使用 indexOf() 和 Pattern/Matcher 组合,但我的结果都不是很优雅,有人有优雅的解决方案吗?
cheers!
干杯!
采纳答案by Joey
Well, you can use a regular expressionto find the cases where "Milan" isn't followed by "Vasic":
好吧,您可以使用正则表达式来查找“Milan”后面没有“Vasic”的情况:
Milan(?! Vasic)
and replace that by the full name:
并用全名替换它:
String.replaceAll("Milan(?! Vasic)", "Milan Vasic")
The (?!...)
part is a negative lookaheadwhich ensures that whatever matches isn't followed by the part in parentheses. It doesn't consume any characters in the match itself.
该(?!...)
部分是一个负面的前瞻,确保任何匹配项后面都没有括号中的部分。它不消耗匹配本身中的任何字符。
Alternatively, you can simply insert (well, technically replacing a zero-width match) the last name after the first name, unless it's followed by the last name already. This looks similar, but uses a positive lookbehindas well:
或者,您可以简单地在名字后面插入(好吧,技术上替换零宽度匹配)姓氏,除非它后面已经跟有姓氏。这看起来很相似,但也使用了积极的回顾:
(?<=Milan)(?! Vasic)
You can replace this by just " Vasic"
(note the space at the start of the string):
您可以将其替换为" Vasic"
(注意字符串开头的空格):
String.replaceAll("(?<=Milan)(?! Vasic)", " Vasic")
You can try those things out herefor example.
例如,您可以在这里尝试这些东西。
回答by Markus Lausberg
When you dont want to put your hand yon regular expression (may be you should) you could first replace all "Milan Vasic" string with "Milan".
当你不想把你的手放在正则表达式上时(可能你应该这样做),你可以先用“米兰”替换所有的“米兰瓦西克”字符串。
And than replace all "Milan" Strings with "Milan Vasic".
然后用“Milan Vasic”替换所有“Milan”字符串。
回答by Fabian Steeg
One possibility, reducing the longer form before expanding all:
一种可能性,在展开所有之前减少较长的形式:
string.replaceAll("Milan Vasic", "Milan").replaceAll("Milan", "Milan Vasic")
Another way, treating Vasicas optional:
另一种方式,将Vasic视为可选:
string.replaceAll("Milan( Vasic)?", "Milan Vasic")
Others have described solutions based on lookaheador alternation.
回答by McDowell
Another option:
另外一个选项:
"My name is Milan, people know me as Milan Vasic"
.replaceAll("Milan Vasic|Milan", "Milan Vasic"))
回答by Alasdair
Simply include the Apache Commons LangJAR and use the org.apache.commons.lang.StringUtils class. You'll notice lots of methods for replacing Strings safely and efficiently.
只需包含Apache Commons LangJAR 并使用 org.apache.commons.lang.StringUtils 类。您会注意到许多安全有效地替换字符串的方法。
You can view the StringUtils API at the previously linked website.
您可以在之前链接的网站上查看 StringUtils API。
"Don't reinvent the wheel"
“不要重新发明轮子”
回答by lsiu
Try this:
尝试这个:
public static void main(String[] args) {
String str = "My name is Milan, people know me as Milan Vasic.";
Pattern p = Pattern.compile("(Milan)(?! Vasic)");
Matcher m = p.matcher(str);
StringBuffer sb = new StringBuffer();
while(m.find()) {
m.appendReplacement(sb, "Milan Vasic");
}
m.appendTail(sb);
System.out.println(sb);
}
回答by GuruKulki
you can use pattern matcher as well, which will replace all in one shot.
您也可以使用模式匹配器,它将一次性替换所有内容。
Pattern keyPattern = Pattern.compile(key); Matcher matcher = keyPattern.matcher(str); String nerSrting = matcher.replaceAll(value);
模式 keyPattern = Pattern.compile(key); 匹配器 matcher = keyPattern.matcher(str); String nerSrting = matcher.replaceAll(value);