Just a note, regexes are not really good for doing "not" semantics outside of character classes. So, I would suggest concentrating on what you do want to keep and build your result from that:
String s = "mpla 12.5 mpla 121.22 mpla 1.52 mpla 1 mpla 1000 mpla 1000.12 mpla12.5";
Pattern p = Pattern.compile("[A-Za-z]+|\\s(\\d{1,3}(\\.\\d{1,2})?\\s)?");
Matcher m = p.matcher(s);
StringBuffer sb = new StringBuffer();
while (m.find()) {
sb.append(m.group());
}
System.out.println(sb.toString());
Outputs:
mpla 12.5 mpla 121.22 mpla 1.52 mpla mpla mpla mpla
I think that this is what you are asking for in the strictest sense -- note that there are multiple spaces in the result that you will have to sanitize if desired.
Edit: Let me clarify what I mean by regexes are not really good for doing "not" semantics outside of character classes
. If you just wanted to "match any character that isn't a letter or whitespace" that would be easy with a negated character class: [^A-Za-z\\s]
. However, once you start needing negations of multi-character groupings (\\d{1,3}\\.\\d{1,2}
for example) it gets ugly. You can technically do it using negative lookaheads, but it's kludgy and not very intuitive. This post explains it well: https://stackoverflow.com/a/406408/1311394
Edit 2: Based on your comments, I believe that a solution utilizing String.split()
along with regex matching will do what you want much easier:
String s = "12.5 mpla 12.5 mpla 121.22 mpla 1.52 mpla 1 mpla 1000 mpla 1000.12 mpla12.5";
StringBuilder sb = new StringBuilder();
for (String token : s.split("\\s+")) {
if (token.matches("[A-Za-z]+|\\d{1,3}(\\.\\d{1,2})?")) {
sb.append(token).append(" ");
}
}
System.out.println(sb.toString());
Output:
12.5 mpla 12.5 mpla 121.22 mpla 1.52 mpla 1 mpla mpla
This should take care of the cases mentioned in the comments. Most of the time a very complex regex is a code smell, and there's usually a simpler way to solve the problem.