String.replaceAll()方法:如何确保永远不会再次替换已处理的字符

时间:2013-10-13 02:16:29

标签: java regex string

我正在读取一个包含以下两行的文件:“hello hi”和“hii hey”。 每行的第一个字符串是正则表达式,第二个是替换字符串,即String.replaceAll(“hello”,“hi”)。我应该通过文件中的每一行来替换字符串中的正则表达式替换。但是有一个问题。永远不应再次替换已处理的字符。

例如我有这个字符串:“helloi”。 在第一行之后,我有“hii”。 在第二行之后,天真的方法将导致“嘿”。

我想确保“hii”仍然保持为“hii”,因为它已包含已处理的字符。

请注意,我正在使用的字符串(“helloi”)只是一个简单的字符串,实际的字符串将很大并包含多行。

你是如何实现的?

编辑:让我用一个例子来更清楚地解释我的情况。我有一个字符串“helloi hii”。在文件的第一行之后,我有“hii hii”。但在第二行之后,我会“嘿嘿”。第一个“hii”包含已处理的字符,因此不会被替换

3 个答案:

答案 0 :(得分:1)

我想每次拨打String.replaceAll时,都应将搜索和替换字符串插入HashSet。在致电String.replaceAll之前,请检查此HashSet中是否存在搜索和替换字符串。

只有在HashSet中不存在搜索和替换字符串时,才会调用String.replaceAll

// at start
Set<String> processed = new HashSet<String>(); 

// read file line by line and have this inside your file processing loop

if (!processed.contains(search) && !processed.contains(replacement)) {
   String repl = line.replaceAll(search, replacement);
   processed.add(search);
   processed.add(replacement);
}

答案 1 :(得分:1)

我不完全确定我理解,但是你可以使用字符串属性和布尔属性创建自己的类来指示它是否已被修改?将您的字符串拆分为该类的数组并处理每个字符串。

答案 2 :(得分:1)

String.replaceAll()可能不会为你完成这项工作。

我会建议类似于这个伪代码的东西

replacements -> HashMap<String, String>
StringBuffer result
regexStr = "("
for each key in replacements
    regexStr += key + "|" //key MUST not have any regex syntax or must be properly escaped
regexStr remove last '|' append ")"
Matcher m = Pattern.compile(regexStr).matcher()
while(matches) {
    get next match
    result.append(match group 1)
    result.append(replacements.get(match group 2))
}

本质:

保留所有替换品的地图:

hi->woah
hello->hi
hey->what's up
what\'s up->fun

您搜索与正则表达式(.*?)(hi|hello|hey|what\'s up)匹配的字符串,这是所有地图键(即您要搜索的内容)。 \将以"what\\s up"的形式出现在Java文字中,因为正则表达式字符串需要知道要逃避'

每次迭代,查看捕获的内容。第一组是自上次比赛以来的一切。第二组是要替换的单词/短语。如果单词“hi”,你想用“woah”替换它,那么在你的地图中查找替换为“hi”。