注意点として、正規表現は、文字クラスの外部で「not」セマンティクスを実行するのにはあまり適していません。だから、私はあなたが維持したいものに集中し、それからあなたの結果を構築することをお勧めします:
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
これは、コメントで言及されているケースを処理する必要があります。ほとんどの場合、非常に複雑な正規表現はコードの臭いであり、通常、問題を解決するためのより簡単な方法があります。