0

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;
}
TacoB2018
  • 33
  • 4
  • 1
    Possible duplicate of [Find and replace words/lines in a file](https://stackoverflow.com/questions/3935791/find-and-replace-words-lines-in-a-file) – Centos Nov 26 '18 at 13:20
  • You want to replace a literal string. Why would you use a regex? Also, replaceAll doesn't return the number of replacements, so how could it work? – JB Nizet Nov 26 '18 at 13:21

1 Answers1

0

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++;
}
Sweeper
  • 145,870
  • 17
  • 129
  • 225