空白匹配正则表达式 - Java

98 java regex whitespace

正则表达式的Java API 声明\s将匹配空格.所以正则表达式\\s\\s应匹配两个空格.

Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");
Run Code Online (Sandbox Code Playgroud)

这样做的目的是用一个空格替换两个连续空格的所有实例.然而,这实际上并不起作用.

我对正则表达式或"空白"这个词有严重的误解吗?

tch*_*ist 184

您不能\s在Java中使用它来匹配其自己的本机字符集上的空白区域,因为Java不支持Unicode空白属性 - 即使这样做是严格要求满足UTS#18的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 + "]";
Run Code Online (Sandbox Code Playgroud)

现在你可以whitespace_charclass + "+"用作你的模式replaceAll.


\w

抱歉'回合所有这一切.Java的正则表达式在它自己的原生字符集上效果不佳,因此你必须跳过异国情调的箍来使它们工作.

如果你认为白色空间不好,你应该看看你需要做些什么才能获得\b\s最终表现得正常!

是的,这是可能的,是的,这是一个令人头疼的混乱.这甚至是慈善事业.为Java提供符合标准的正则表达式库的最简单方法是将JNI转换为ICU的东西.这就是谷歌为Android所做的事情,因为OraSun并没有达到目标.

如果您不想这样做但仍想坚持使用Java,我有一个前端正则表达式重写库我写道"修复"Java的模式,至少是为了使它们符合UTSRL1.2a的要求#18,Unicode正则表达式.

\p{White_Space}

  • 感谢Java对正则表达式的限制.+1 (10认同)
  • 这真的很古老.使用UNICODE_CHARACTER_CLASS标志在java7中修复了这是否正确?(或使用(?U)) (5认同)
  • @tchrist如果在java 7+中修复了这个问题,你能用现在正确的方法更新答案吗? (5认同)
  • 使用Java 7+,您可以:"(?U)\ s"运行符合Unicode技术标准的正则表达式.或者,您可以在创建模式时使UNICODE_CHARACTER_CLASS标志为true.这是doc:https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS (5认同)
  • 我把这个答案投票给了帮助,发现我已经有了.谢谢你*第二次*时间:) (4认同)
  • @kritzikratzi是的. (3认同)
  • 上面的代码缺少 \\u200B (ZERO WIDTH SPACE) (3认同)
  • 重写 `\s` 的更短方法是 `[\s\u0085\p{Z}]`。 (2认同)

Rap*_*ien 42

是的,你需要获取matcher.replaceAll()的结果:

String result = matcher.replaceAll(" ");
System.out.println(result);
Run Code Online (Sandbox Code Playgroud)

  • 嘎.我觉得自己是地球上最大的白痴.我和其他两个人似乎都没有注意到这一点.我想最愚蠢的小错误有时会让我们失望,是吗? (16认同)

sur*_*sea 13

对于Java(不是PHP,不是javascript,不是任何其他):

txt.replaceAll("\\p{javaSpaceChar}{2,}"," ")
Run Code Online (Sandbox Code Playgroud)

  • 我知道replaceAll返回一个字符串,重要的是4个java程序员是\\ p {javaSpaceChar} (6认同)
  • 最初的问题是错误的是没有将新字符串赋给变量.因此,指出这个错误是答案中最重要的一点. (2认同)

Rob*_*ert 11

自从这个问题首次提出以来,Java 已经不断发展。您可以使用该\p{Zs}组来匹配所有形式的 unicode 空格字符。

因此,如果您想用普通空格替换一个或多个奇异空格,您可以这样做:

String txt = "whatever my string is";
String newTxt = txt.replaceAll("\\p{Zs}+", " ");
Run Code Online (Sandbox Code Playgroud)

另外值得了解的是,如果您使用过trim()字符串函数,您应该看看(相对较新的)字符串上的strip()stripLeading()stripTrailing()函数。它们可以帮助您修剪掉各种松散的空白字符。更多关于什么空间包含什么内容,请参见Java的Character.isWhitespace()函数。


Wik*_*żew 6

要匹配任何空白字符,您可以使用

Pattern whitespace = Pattern.compile("\\s", Pattern.UNICODE_CHARACTER_CLASS);
Run Code Online (Sandbox Code Playgroud)

Pattern.UNICODE_CHARACTER_CLASS选项“启用预定义字符类和 POSIX 字符类的 Unicode 版本”,然后“符合Unicode 技术标准 #18:Unicode 正则表达式附件 C:兼容性属性”。

使用嵌入的标志表达式也可以启用相同的行为(?U)。例如,如果你想用正则表达式替换/删除 Java 中的所有 Unicode 空格,你可以使用

String result = text.replaceAll("(?U)\\s+", ""); // removes all whitespaces
String result = text.replaceAll("(?U)\\s", "-"); // replaces each single whitespace with -
String result = text.replaceAll("(?U)\\s+", "-"); // replaces chunks of one or more consecutive whitespaces with a single -
String result = text.replaceAll("(?U)\\G\\s", "-"); // replaces each single whitespace at the start of string with -
Run Code Online (Sandbox Code Playgroud)

在线查看Java 演示:

String text = "\u00A0 \u00A0\tStart reading\u00A0here..."; // \u00A0 - non-breaking space
System.out.println("Text: '" + text + "'"); // => Text: '       Start reading here...'
System.out.println(text.replaceAll("(?U)\\s+", "")); // => Startreadinghere...
System.out.println(text.replaceAll("(?U)\\s", "-")); // => ----Start-reading-here...
System.out.println(text.replaceAll("(?U)\\s+", "-")); // => -Start-reading-here...
System.out.println(text.replaceAll("(?U)\\G\\s", "-")); // => ----Start reading here... 
Run Code Online (Sandbox Code Playgroud)


Mih*_*der 5

似乎对我有用:

String s = "  a   b      c";
System.out.println("\""  + s.replaceAll("\\s\\s", " ") + "\"");
Run Code Online (Sandbox Code Playgroud)

将打印:

" a  b   c"
Run Code Online (Sandbox Code Playgroud)

我认为你打算这样做而不是你的代码:

Pattern whitespace = Pattern.compile("\\s\\s");
Matcher matcher = whitespace.matcher(s);
String result = "";
if (matcher.find()) {
    result = matcher.replaceAll(" ");
}

System.out.println(result);
Run Code Online (Sandbox Code Playgroud)


小智 5

当我向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的代码,正如该问题中接受的答案所指出的那样."

  • `[\ s\p {z}]`省略Unicode"下一行"字符U + 0085.使用`[\ s\u0085\p {Z}]`. (2认同)