所以对于这个Allow PosixPrint Characters except , % \ / # ? :
条件是有效的
这个正则表达式模式m/^[^\P{PosixPrint}\/\#\%\?\:\,\\]+$/x
但为此:
white-space at the beginning and end but allow in the middle
这种模式m/^\b[^\P{PosixPrint}\/\#\%\?\:\,\\]+\b$/x
有点工作(见输出)。
如果除[0-9a-zA-Z]
之外的任何字符出现在开头和结尾,则它不匹配字符串。
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $vars = [
q#1#,
q#1~`!l#,
q#11#,
q#111#,
q#1 1#,
q# 11#,
q#11 #,
q# 11 #,
q# 1 1 #,
q#1`~!@$^&*()-_=+|]}[{;'".><1#,
q#1`~!@$^&*()-_=1#,
q#1~`!@$^&*()-_=+|]}[{;'".><#,
q#~`!@$^&*()-_=+|]}[{;'".><1#,
q#~`!@$^&*()-_=+|]}[{;'".><#,
];
foreach my $var (@$vars){
if ( $var =~ m/^\b[^\P{PosixPrint}\/\#\%\?\:\,\\]+\b$/x) {
print "match:\t\t#$var#\n";
}
else{
print "no match:\t#$var#\n";
}
}
OUTPUT:
match: #1#
match: #1~`!l#
match: #11#
match: #111#
match: #1 1#
no match: # 11#
no match: #11 #
no match: # 11 #
no match: # 1 1 #
match: #1`~!@$^&*()-_=+|]}[{;'".><1#
match: #1`~!@$^&*()-_=1#
no match: #1~`!@$^&*()-_=+|]}[{;'".><#
no match: #~`!@$^&*()-_=+|]}[{;'".><1#
no match: #~`!@$^&*()-_=+|]}[{;'".><#
预期产量:
match: #1#
match: #1~`!l#
match: #11#
match: #111#
match: #1 1#
no match: # 11#
no match: #11 #
no match: # 11 #
no match: # 1 1 #
match: #1`~!@$^&*()-_=+|]}[{;'".><1#
match: #1`~!@$^&*()-_=1#
match: #1~`!@$^&*()-_=+|]}[{;'".><#
match: #~`!@$^&*()-_=+|]}[{;'".><1#
match: #~`!@$^&*()-_=+|]}[{;'".><#
信息:
Perl Version: v5.26.2
Platform: Ubuntu 18.10
\b
是一个单词边界,它是单词字符和非单词字符之间的边界。
行的开头和结尾被视为非单词字符,因此,只有在第一个(最后一个)字符处有单词字符时,行末或行开头的\b
才会“匹配”。
据我了解,您想要拒绝以空格开头和/或结尾的行,请使用:
my $vars = [
q#1#,
q#1~`!l#,
q#11#,
q#111#,
q#1 1#,
q# 11#,
q#11 #,
q# 11 #,
q# 1 1 #,
q#1`~!@$^&*()-_=+|]}[{;'".><1#,
q#1`~!@$^&*()-_=1#,
q#1~`!@$^&*()-_=+|]}[{;'".><#,
q#~`!@$^&*()-_=+|]}[{;'".><1#,
q#~`!@$^&*()-_=+|]}[{;'".><#,
];
foreach my $var (@$vars){
if ( $var =~ m/^(?!\h)[^\P{PosixPrint}\/\#\%\?\:\,\\]+(?<!\h)$/x) {
# ^^^^^^ ^^^^^^^
print "match:\t\t#$var#\n";
}
else{
print "no match:\t#$var#\n";
}
}
哪里
(?!\h)
是一个负面的先行者,确保我们在第一个位置没有水平空间(?<!\h)
是一个消极的外观,确保我们在最后位置没有水平空间输出:
match: #1#
match: #1~`!l#
match: #11#
match: #111#
match: #1 1#
no match: # 11#
no match: #11 #
no match: # 11 #
no match: # 1 1 #
match: #1`~!@$^&*()-_=+|]}[{;'".><1#
match: #1`~!@$^&*()-_=1#
match: #1~`!@$^&*()-_=+|]}[{;'".><#
match: #~`!@$^&*()-_=+|]}[{;'".><1#
match: #~`!@$^&*()-_=+|]}[{;'".><#
以下是早期答案提供的模式,其中包含一些修复:
/
^
(?!\s)
[^\P{PosixPrint}\\\/\#%?:,]*
(?<!\s)
\z
/x
以下是对以上内容的优化:
/
^
(?: [^\P{PosixPrint}\s\\\/\#%?:,]++
(?: [^\P{PosixPrint}\S]++
[^\P{PosixPrint}\s\\\/\#%?:,]++
)*+
)?+
\z
/x
更好的做法是说明允许哪些字符(白名单)而不是说明哪些字符不是(黑名单)。后一种方法容易出错。以下内容与上述解决方案相同,但使用白名单而不是黑名单:
/
^
(?: [a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~]++
(?: [ ]++
[a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~]++
)*+
)?+
\z
/x
要么
/
^
(?: (?&SAFE_CHAR)++
(?: [ ]++
(?&SAFE_CHAR)++
)*+
)?+
\z
(?(DEFINE)
(?<SAFE_CHAR> [a-zA-Z0-9!"\$&'()*+\-.;<=>@[\]^_`{|}~] )
)
/x