因此对于此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";
}
}
输出:
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
答案 0 :(得分:3)
\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: #~`!@$^&*()-_=+|]}[{;'".><#
答案 1 :(得分:2)
以下是先前答案提供的模式,并进行了一些修复:
/
^
(?!\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