regular expressions的Java API声明\s
将匹配空格。所以正则表达式\\s\\s
应该匹配两个空格。
Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");
这样做的目的是用一个空格替换两个连续空格的所有实例。然而,这实际上并不起作用。
我对正则表达式或“空白”这个词有严重的误解吗?
是的,你需要获取matcher.replaceAll()的结果:
String result = matcher.replaceAll(" ");
System.out.println(result);
您不能在Java中使用\s
来匹配其自己的本机字符集上的空白区域,因为Java不支持Unicode白色空间属性 - 即使严格要求这样做以满足UTS#18’s RL1.2!它所具有的不符合标准唉。
Unicode将26个代码点定义为\p{White_Space}
:其中20个是各种类型的\pZ
GeneralCategory = Separator,其余6个是\p{Cc}
GeneralCategory = Control。
白色空间是一个相当稳定的属性,而那些相同的空间几乎永远存在。即便如此,Java没有符合这些标准的Unicode标准,所以你必须使用这样的代码:
String whitespace_chars = "" /* dummy empty string for homogeneity */
+ "\\u0009" // CHARACTER TABULATION
+ "\\u000A" // LINE FEED (LF)
+ "\\u000B" // LINE TABULATION
+ "\\u000C" // FORM FEED (FF)
+ "\\u000D" // CARRIAGE RETURN (CR)
+ "\\u0020" // SPACE
+ "\\u0085" // NEXT LINE (NEL)
+ "\\u00A0" // NO-BREAK SPACE
+ "\\u1680" // OGHAM SPACE MARK
+ "\\u180E" // MONGOLIAN VOWEL SEPARATOR
+ "\\u2000" // EN QUAD
+ "\\u2001" // EM QUAD
+ "\\u2002" // EN SPACE
+ "\\u2003" // EM SPACE
+ "\\u2004" // THREE-PER-EM SPACE
+ "\\u2005" // FOUR-PER-EM SPACE
+ "\\u2006" // SIX-PER-EM SPACE
+ "\\u2007" // FIGURE SPACE
+ "\\u2008" // PUNCTUATION SPACE
+ "\\u2009" // THIN SPACE
+ "\\u200A" // HAIR SPACE
+ "\\u2028" // LINE SEPARATOR
+ "\\u2029" // PARAGRAPH SEPARATOR
+ "\\u202F" // NARROW NO-BREAK SPACE
+ "\\u205F" // MEDIUM MATHEMATICAL SPACE
+ "\\u3000" // IDEOGRAPHIC SPACE
;
/* A \s that actually works for Java’s native character set: Unicode */
String whitespace_charclass = "[" + whitespace_chars + "]";
/* A \S that actually works for Java’s native character set: Unicode */
String not_whitespace_charclass = "[^" + whitespace_chars + "]";
现在你可以使用whitespace_charclass + "+"
作为replaceAll
中的模式。
抱歉'回合所有这一切。 Java正则表达式在它自己的原生字符集上运行得不好,所以你真的必须跳过异国情调的箍来使它们工作。
如果你认为白色空间不好,你应该看看你需要做些什么来让\w
和\b
最终表现得很好!
是的,这是可能的,是的,这是一个令人头疼的混乱。这甚至是慈善事业。为Java提供符合标准的正则表达式库的最简单方法是将JNI转换为ICU的东西。这就是谷歌为Android所做的事情,因为OraSun并不适合。
如果您不想这样做但仍想坚持使用Java,我有一个前端正则表达式重写库我写道“修复”Java的模式,至少是为了使它们符合RL1.2a in UTS#18, Unicode Regular Expressions的要求。
对于Java(不是php,不是javascript,不是另一个):
txt.replaceAll("\\p{javaSpaceChar}{2,}"," ")
当我向Regexbuddy(正则表达式开发人员应用程序)论坛发出问题时,我得到了更准确的回复我的Java问题:
“致辞作者:Jan Goyvaerts
在Java中,短语\ s,\ d和\ w仅包含ASCII字符。 ...这不是Java中的错误,而只是在使用正则表达式时需要注意的许多事项之一。要匹配所有Unicode空白以及换行符,可以在Java中使用[\ s \ p {Z}]。 RegexBuddy还不支持特定于Java的属性,例如\ p {javaSpaceChar}(与[\ s \ p {Z}]完全相同的字符匹配)。
如果输入仅为ASCII,则\ s \ s将匹配两个空格。真正的问题在于OP的代码,正如该问题中接受的答案所指出的那样。“
似乎为我工作:
String s = " a b c";
System.out.println("\"" + s.replaceAll("\\s\\s", " ") + "\"");
将打印:
" a b c"
我认为你打算这样做而不是你的代码:
Pattern whitespace = Pattern.compile("\\s\\s");
Matcher matcher = whitespace.matcher(s);
String result = "";
if (matcher.find()) {
result = matcher.replaceAll(" ");
}
System.out.println(result);
Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
boolean flag = true;
while(flag)
{
//Update your original search text with the result of the replace
modLine = matcher.replaceAll(" ");
//reset matcher to look at this "new" text
matcher = whitespace.matcher(modLine);
//search again ... and if no match , set flag to false to exit, else run again
if(!matcher.find())
{
flag = false;
}
}
出于您的目的,您可以使用此代码段:
import org.apache.commons.lang3.StringUtils;
StrintUtils.StringUtils.normalizeSpace(string);
这会将间距规范化为单一,并将剥离起始和尾随空格。
出于您的目的,您可以使用此代码段:
import org.apache.commons.lang3.StringUtils;
StrintUtils.StringUtils.normalizeSpace(string);
这会将间距规范化为单一,并将剥离起始和尾随空格。
String sampleString =“Hello world!”; sampleString.replaceAll(“\ s {2}”,“”); //恰好替换两个连续的空格
sampleString.replaceAll(“\ s {2,}”,“”); //替换两个或多个连续的空格
在RE中使用空格是一种痛苦,但我相信它们有效。 OP的问题也可以使用StringTokenizer或split()方法解决。但是,要使用RE(取消注释println()以查看匹配器如何分解String),下面是一个示例代码:
import java.util.regex.*;
public class Two21WS {
private String str = "";
private Pattern pattern = Pattern.compile ("\\s{2,}"); // multiple spaces
public Two21WS (String s) {
StringBuffer sb = new StringBuffer();
Matcher matcher = pattern.matcher (s);
int startNext = 0;
while (matcher.find (startNext)) {
if (startNext == 0)
sb.append (s.substring (0, matcher.start()));
else
sb.append (s.substring (startNext, matcher.start()));
sb.append (" ");
startNext = matcher.end();
//System.out.println ("Start, end = " + matcher.start()+", "+matcher.end() +
// ", sb: \"" + sb.toString() + "\"");
}
sb.append (s.substring (startNext));
str = sb.toString();
}
public String toString () {
return str;
}
public static void main (String[] args) {
String tester = " a b cdef gh ij kl";
System.out.println ("Initial: \"" + tester + "\"");
System.out.println ("Two21WS: \"" + new Two21WS(tester) + "\"");
}}
它生成以下内容(使用javac编译并在命令提示符下运行):
%java Two21WS Initial:“a b cdef gh ij kl”Two21WS:“a b cdef gh ij kl”