I am trying to write a method that accepts an input string to be found and an input string to replace all instances of the found word and to return the number of replacements made. I am trying to use pattern and matcher from JAVA regex. I have a text file called "text.txt" which includes "this is a test this is a test this is a test". When I try to search for "test" and replace it with "mess", the method returns 1 each time and none of the words test are replaced.
public int findAndRepV2(String word, String replace) throws FileNotFoundException, IOException
{
int cnt = 0;
BufferedReader input = new BufferedReader( new FileReader(this.filename));
Writer fw = new FileWriter("test.txt");
String line = input.readLine();
while (line != null)
{
Pattern pattern = Pattern.compile(word, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(line);
while (matcher.find()) {matcher.replaceAll(replace); cnt++;}
line = input.readLine();
}
fw.close();
return cnt;
}
First, you need to ensure that the text you are searching for is not interpreted as a regex. You should do:
Pattern pattern = Pattern.compile(Pattern.quote(word), Pattern.CASE_INSENSITIVE);
Second, replaceAll
does something like this:
public String replaceAll(String replacement) {
reset();
boolean result = find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
appendReplacement(sb, replacement);
result = find();
} while (result);
appendTail(sb);
return sb.toString();
}
return text.toString();
}
Note how it calls find
until it can't find anything. This means that your loop will only be run once, since after the first call to replaceAll
, the matcher has already found everything.
You should use appendReplacement
instead:
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buffer, replace);
cnt++;
}
buffer.append(line.substring(matcher.end()));
// "buffer" contains the string after the replacement
I noticed that in your method, you didn't actually do anything with the string after the replacement. If that's the case, just count how many times find
returns true:
while (matcher.find()) {
cnt++;
}