使用双负片:
/[^\S\r\n]/
也就是说,不是空白(大写的S补码),也不是回车,也不是换行。分配外部非(
即
,补充
^
在字符类)中
De Morgan's law
,这相当于空白,但不是回车或换行。包括两者
\r
和
\n
在该模式中,正确处理所有Unix(LF)、经典Mac OS(CR)和DOS ISH(CRLF)
newline conventions
.
不必相信我的话:
#! /usr/bin/env perl
use strict;
use warnings;
use 5.005; # for qr//
my $ws_not_crlf = qr/[^\S\r\n]/;
for (' ', '\f', '\t', '\r', '\n') {
my $qq = qq["$_"];
printf "%-4s => %s\n", $qq,
(eval $qq) =~ $ws_not_crlf ? "match" : "no match";
}
输出:
" " => match
"\f" => match
"\t" => match
"\r" => no match
"\n" => no match
在Perlv5.18之前,
\s
与垂直选项卡不匹配。
[^\S\cK]
(模糊地)匹配什么
的S
传统上是这样。
外部区域设置和Unicode规则,或者当
/a
开关有效,
的S
比赛
[\t\n\f\r ]
从Perlv5.18开始,垂直标签,
\cK
. 丢弃
R
和
\n
离开
/[\t\f\cK ]/
用于匹配空白而不是换行符。
sub ws_not_nl {
local($_) = <
0x0009 CHARACTER TABULATION h s
0x000a LINE FEED (LF) vs
0x000b LINE TABULATION vs [1]
0x000c FORM FEED (FF) vs
0x000d CARRIAGE RETURN (CR) vs
0x0020 SPACE h s
0x0085 NEXT LINE (NEL) vs [2]
0x00a0 NO-BREAK SPACE h s [2]
0x1680 OGHAM SPACE MARK h s
0x2000 EN QUAD h s
0x2001 EM QUAD h s
0x2002 EN SPACE h s
0x2003 EM SPACE h s
0x2004 THREE-PER-EM SPACE h s
0x2005 FOUR-PER-EM SPACE h s
0x2006 SIX-PER-EM SPACE h s
0x2007 FIGURE SPACE h s
0x2008 PUNCTUATION SPACE h s
0x2009 THIN SPACE h s
0x200a HAIR SPACE h s
0x2028 LINE SEPARATOR vs
0x2029 PARAGRAPH SEPARATOR vs
0x202f NARROW NO-BREAK SPACE h s
0x205f MEDIUM MATHEMATICAL SPACE h s
0x3000 IDEOGRAPHIC SPACE h s
EOTable
my $class;
while (/^0x([0-9a-f]{4})\s+([A-Z\s]+)/mg) {
my($hex,$name) = ($1,$2);
next if $name =~ /\b(?:CR|NL|NEL|SEPARATOR)\b/;
$class .= "\\N{U+$hex}";
}
qr/[$class]/u;
}
其他应用
双重否定技巧对于匹配字母字符也很方便。记住
\w
匹配单词字符、字母字符
和
数字和下划线。我们这些丑陋的美国人有时想把它写成,比如,
if (/[A-Za-z]+/) { ... }
但是双重否定字符类可以尊重区域设置:
if (/[^\W\d_]+/) { ... }
用这种方式表达单词字符而不是数字或下划线有点不透明。posix字符类更直接地传达意图。
if (/[[:alpha:]]+/) { ... }
或使用Unicode属性作为
szbalint
建议
if (/\p{Letter}+/) { ... }