Remove Re: Fwd: from Mail subjects

Viewed 227

I'm trying to put up a regex to remove extra keywords from the mail subjects, added generally by mail composers like Fwd, Re: But not able to come up with a regex that can satisfy all these scenarios.

Fwd : Re : Re: Many
Re : Re: Many
Re:    Re: Many
Re: Many
Re: Many
RE: Presidential Ballots for Florida
RE: (no subject)
Request - should not match anything
this is the subject
Re: Fwd

I tried with this regex in Java:

subject.replaceAll("^.{0,3}:\s", "");

but this removes only the first match found. Any regex if it can satisfy most of the common scenarios, not all the above will be a great help as well. I found some regex for Python, but converting them into Java is quite a pain. Any help is appreciated.

2 Answers

You might remove the occurrences that are not only bound to the start of the string using:

\b(?:Fwd|Re)\b\h*(?::\h*)?

Regex demo

Note that this will also match the last full line Re: Fwd


If Fwd should not be matched (so the colon is not optional) and bound to the start of the string:

^(?:(?:Fwd|Re)\h*:\h*)+

Explanation

  • ^ Start of string
  • (?: Non capture group
    • (?:Fwd|Re)\h*:\h* Match either Fwd or Re followed by a colon between optional horizontal whitespaces
  • )+ Close the non capture group and repeat 1+ times to get all occurrences

Regex demo | Java demo

Example

String regex = "^(?:(?:Fwd|Re)\\h*:\\h*)+";
String string = "Fwd : Re : Re: Many\n"
     + "Re : Re: Many\n"
     + "Re:    Re: Many\n"
     + "Re: Many\n"
     + "Re: Many\n"
     + "RE: Presidential Ballots for Florida\n"
     + "RE: (no subject)\n"
     + "Request - should not match anything\n"
     + "this is the subject\n"
     + "Re: Fwd";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(string);
String result = matcher.replaceAll("");

System.out.println(result);

Output

Many
Many
Many
Many
Many
Presidential Ballots for Florida
(no subject)
Request - should not match anything
this is the subject
Fwd

You can use the regex, ((?mi)(fwd|re)\s*:\s*)

public class Main {
    public static void main(String[] args) {
        String s = "Fwd : Re : Re: Many\n" + 
                "Re : Re: Many\n" + 
                "Re:    Re: Many\n" + 
                "Re: Many\n" + 
                "Re: Many\n" + 
                "RE: Presidential Ballots for Florida\n" + 
                "RE: (no subject)\n" + 
                "Request - should not match anything\n" + 
                "this is the subject\n" + 
                "Re: Fwd" ;
        
        System.out.println(s.replaceAll("((?mi)(fwd|re)\\s*:\\s*)", ""));   
    }
}

Output:

Many
Many
Many
Many
Many
Presidential Ballots for Florida
(no subject)
Request - should not match anything
this is the subject
Fwd

Explanation of the regex:

  1. (?mi) specifies multiline and case-insensitive.
  2. (fwd|re) specifies fwd or re.
  3. \s* specifies any number of whitespace characters.
Related