匹配空格而不是换行符
我有时想匹配空白,但不是换行符。
到目前为止,我一直在诉诸于[ \t]
。 有没有一个尴尬的方式?
Perl版本5.10和更高版本支持附属的垂直和水平字符类\v
和\h
以及通用空白字符类\s
最干净的解决scheme是使用水平空白字符类\h
。 这将匹配ASCII集中的制表符和空格,扩展ASCII的非中断空格或任何这些Unicode字符
U+0009 CHARACTER TABULATION U+0020 SPACE U+00A0 NO-BREAK SPACE (not matched by \s) U+1680 OGHAM SPACE MARK U+2000 EN QUAD U+2001 EM QUAD U+2002 EN SPACE U+2003 EM SPACE U+2004 THREE-PER-EM SPACE U+2005 FOUR-PER-EM SPACE U+2006 SIX-PER-EM SPACE U+2007 FIGURE SPACE U+2008 PUNCTUATION SPACE U+2009 THIN SPACE U+200A HAIR SPACE U+202F NARROW NO-BREAK SPACE U+205F MEDIUM MATHEMATICAL SPACE U+3000 IDEOGRAPHIC SPACE
垂直空间模式\v
不太有用,但匹配这些字符
U+000A LINE FEED U+000B LINE TABULATION U+000C FORM FEED U+000D CARRIAGE RETURN U+0085 NEXT LINE (not matched by \s) U+2028 LINE SEPARATOR U+2029 PARAGRAPH SEPARATOR
有7个匹配\v
垂直空白字符和18个匹配\h
水平字符。 匹配二十三个字符
所有的空白字符都是垂直或水平的 ,没有重叠,但是它们不是合适的子集,因为\h
也匹配U + 00A0无间隔空间, \v
也匹配U + 0085 NEXT LINE,两者都不匹配\s
使用双重否定:
/[^\S\n]/
为了避免在perlport中关于\r
和\n
映射提出的平台差异:
/[^\S\x0a\x0d]/
也就是说,不是非空白或不是新行,对于不包括CR和NL的模式类似。
按照德摩根定律将外在的( 即在angular色阶级中的补充)分配,这相当于“空白而不是回车而不是换行”,但不要听我说:
#! /usr/bin/env perl use strict; use warnings; use 5.005; # for qr// my $ws_not_nl = qr/[^\S\x0a\x0d]/; for (' ', '\f', '\t', '\r', '\n') { my $qq = qq["$_"]; printf "%-4s => %s\n", $qq, (eval $qq) =~ $ws_not_nl ? "match" : "no match"; }
输出:
“”=>匹配 “\ f”=>匹配 “\ t”=>匹配 “\ r”=>不匹配 “\ n”=>不匹配
请注意排除垂直选项卡,但在v5.18中解决了这个问题 。
这个技巧也适用于匹配字母字符。 请记住, \w
匹配“单词字符”,字母字符, 还有数字和下划线。 我们丑陋的美国人有时候想把它写成,比如说,
if (/^[A-Za-z]+$/) { ... }
但是双重否定的字符类可以尊重语言环境:
if (/^[^\W\d_]+$/) { ... }
这有点不透明,所以POSIXangular色可能会更好地expression意图
if (/^[[:alpha:]]+$/) { ... }
或者按照szbalint的build议
if (/^\p{Letter}+$/) { ... }
格雷格的回答也包括回车的一个变种:
/[^\S\r\n]/
这个正则expression式比/[^\S\n]/
没有\r
更安全。 我的推理是,Windows使用\r\n
换行,Mac OS 9使用\r
。 现在你不可能find\r
\n
,但是如果你确实find了它,那么除了换行符之外别无它物。 因此,由于\r
可以表示一个换行符,我们也应该排除它。
下面的正则expression式将匹配空格,但不是新的行字符。
(?:(?!\n)\s)
DEMO
如果你想添加回车也可以用\r
添加\r
在负向预测之内的操作员。
(?:(?![\n\r])\s)
DEMO
在非捕获组之后添加+
以匹配一个或多个空格。
(?:(?![\n\r])\s)+
DEMO
我不知道你们为什么没有提到与任何水平空格( 空格和制表符 )匹配的POSIX字符类[[:blank:]]
。 这个POSIX字符类可以在BRE( Basic REgular Expressions ),ERE( 扩展正则expression式 ),PCRE( Perl兼容正则expression式 )上工作。
DEMO
你在找什么是POSIX blank
字符类。 在Perl中它被引用为:
[[:blank:]]
在Java中(不要忘记启用UNICODE_CHARACTER_CLASS
):
\p{Blank}
与类似的\h
相比,POSIX blank
由更多的正则引擎( 引用 )支持。 一个主要的好处是它的定义在Unicode正则expression式的附录C:兼容性属性和在所有支持Unicode的正则expression式中都是标准的。 (例如,在Perl中, \h
select另外包含MONGOLIAN VOWEL SEPARATOR
)。然而,赞成\h
一个论点是它总是检测Unicode字符(即使引擎不同意哪个),而POSIX字符类通常默认只有ASCII(如Java)。
但问题是,即使坚持Unicode也不能解决问题100%。 考虑以下在Unicode中不被认为是空白的字符:
- U + 180E蒙古语VELEL分隔符
- U + 200B零宽度空间
- U + 200C零宽度非连接器
- U + 200D零宽度连接器
- U + 2060 WORD JOINER
-
U + FEFF零宽度非破坏空间
前面提到的蒙古元音分隔符不包括在内,可能是一个很好的理由。 它与200C和200D一起出现在文字(AFAIK)中,因此打破了所有其他空白符合的基本规则:您可以用它来标记。 他们更像修饰语。 但是,“ ZERO WIDTH SPACE
,“ WORD JOINER
”和“ ZERO WIDTH NON-BREAKING SPACE
(如果它不是字节顺序标记)符合我的书中的空白规则。 因此,我将它们包含在我的水平空白字符类中。
在Java中:
static public final String HORIZONTAL_WHITESPACE = "[\\p{Blank}\\u200B\\u2060\\uFFEF]"
m/ /g
只是给/ /
空间,它会工作。 或者使用\S
– 它将replace所有特殊字符,如制表符,换行符,空格等等。