请注意,正则表达式并不适合在字符类之外执行“非”语义。因此,我建议专注于您想要保留的内容并从中构建您的结果:
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());
输出:
mpla 12.5 mpla 121.22 mpla 1.52 mpla mpla mpla mpla
我认为这是您最严格意义上的要求——请注意,结果中有多个空格,如果需要,您必须对其进行清理。
编辑:让我澄清一下我的意思regexes are not really good for doing "not" semantics outside of character classes
。如果您只是想“匹配任何不是字母或空格的字符”,那么使用否定字符类很容易:[^A-Za-z\\s]
. 但是,一旦您开始需要否定多字符分组(\\d{1,3}\\.\\d{1,2}
例如),它就会变得丑陋。从技术上讲,您可以使用负前瞻来做到这一点,但它很笨拙而且不是很直观。这篇文章很好地解释了它:https ://stackoverflow.com/a/406408/1311394
编辑2:根据您的评论,我相信String.split()
与正则表达式匹配一起使用的解决方案将更轻松地完成您想要的事情:
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());
输出:
12.5 mpla 12.5 mpla 121.22 mpla 1.52 mpla 1 mpla mpla
这应该照顾评论中提到的情况。大多数时候,非常复杂的正则表达式是一种代码异味,通常有一种更简单的方法来解决问题。