简体   繁体   English

Java查找和替换字符串的最佳方法?

[英]Java best way for string find and replace?

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. 我想用米兰瓦西奇代替米兰,但在我已经有米兰瓦西奇的地方,这应该不是一个案例。

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! 干杯!

Well, you can use a regular expression to find the cases where "Milan" isn't followed by "Vasic": 那么,您可以使用正则表达式来查找“米兰”未跟随“Vasic”的情况:

Milan(?! Vasic)

and replace that by the full name: 并用全名替换:

String.replaceAll("Milan(?! Vasic)", "Milan Vasic")

The (?!...) part is a negative lookahead which 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 lookbehind as well: 这看起来很相似,但也使用积极的lookbehind

(?<=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 here for example. 例如,你可以在这里试试这些东西。

Another option: 另外一个选项:

"My name is Milan, people know me as Milan Vasic"
    .replaceAll("Milan Vasic|Milan", "Milan Vasic"))

One possibility, reducing the longer form before expanding all: 一种可能性,在扩展所有之前减少更长的形式:

string.replaceAll("Milan Vasic", "Milan").replaceAll("Milan", "Milan Vasic")

Another way, treating Vasic as optional: 另一种方法,将Vasic视为可选:

string.replaceAll("Milan( Vasic)?", "Milan Vasic")

Others have described solutions based on lookahead or alternation . 其他人已经描述了基于先行替代的解决方案

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”取代所有“米兰”弦乐。

Simply include the Apache Commons Lang JAR and use the org.apache.commons.lang.StringUtils class. 只需包含Apache Commons Lang JAR并使用org.apache.commons.lang.StringUtils类。 You'll notice lots of methods for replacing Strings safely and efficiently. 您会注意到许多安全有效地替换字符串的方法。

You can view the StringUtils API at the previously linked website. 您可以在之前链接的网站上查看StringUtils API。

"Don't reinvent the wheel" “不要重新发明轮子”

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);
}

you can use pattern matcher as well, which will replace all in one shot. 你也可以使用模式匹配器,它将一次性取代所有。

Pattern keyPattern = Pattern.compile(key); 模式keyPattern = Pattern.compile(key); Matcher matcher = keyPattern.matcher(str); Matcher matcher = keyPattern.matcher(str); String nerSrting = matcher.replaceAll(value); String nerSrting = matcher.replaceAll(value);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM