匹配特殊字符 (#@#!~'%^&()[]}{;') 并在 perl 中将其替换为 _(下划线)



我想删除所有特殊字符,除了这个2字符。-

$name=~s/[^wd.-]/_/g ;

但是它上面的行不仅删除了特殊字符,而且删除了非字母字符,例如阿拉伯语或其他非字母字符。

如何删除这些字符 (#@#!~`%^& amp ;()[]}{;',)

这里有几件事需要考虑。

首先,dw真的像你想象的那样吗?最近的perl支持Unicode(在某些情况下支持区域设置),并且这些字符类在每种情况下都不相同。

既然你知道你想要排除什么,你可以直接把它放到字符类中。你只需要转义],这样它就不会结束字符类:

use v5.10;
my $name = "(Hello] #&^% {World[} (#@#!~`%^&()[]}{;',)!";
$name =~ s/[(#@#!~`%^&()[]}{;',)]/_/g;
say $name;

Mark Jason Dominus写过关于"美国人"的文章。和";Prussian"清理数据的方法。您可以指定要排除或包含的内容。

如果指定要排除的内容,则可能会传递一些应该排除但没有排除的内容。这可能是因为你忘记了或者甚至不知道你应该排除它。这些意想不到的情况可能会伤害你。

如果你只指定安全的东西,你可能会错过你应该通过的东西,但是坏的东西是不会因为疏忽而通过的。

你可以试试这个,在你不使用字符类快捷键的地方:

$name =~ s/[^0-9A-Za-z.-]/_/g;

但是输出有点奇怪,因为它也替换了空白。您可以在这里添加s快捷键:

$name =~ s/[^0-9A-Za-zs.-]/_/g;

但是s的含义也随着时间的推移而改变(垂直制表符!),并且也支持Unicode。您可以列出您接受的空格:

$name =~ s/[^0-9A-Za-zx20.-]/_/g;

但是不,这有点奇怪。还有另一种方法。您可以使用/a标志返回到字符类快捷方式的ASCII版本:

$name =~ s/[^dws.-]/_/ga;

regex操作符标志是perlop,因为它们适用于操作符。但是,只要我一直在使用Perl并在课堂上告诉别人,我仍然首先选择perlre。

字译

第二,替换操作符可能比您需要的更多。如果要将单个字符更改为其他单个字符,则可能需要使用音译操作符。它将左边的字符替换为右边相应的字符:

$name =~ tr/abc/XYZ/; # a -> X, b -> Y, c -> Z

如果右边没有足够的字符匹配,它会重用最后一个字符:

$name =~ tr/abc/XY/; # a -> X, b -> Y, c -> Y

所以,在你的例子中只有一个下划线:

$name =~ tr/@#!~`%^&()[]}{;',/_/;

由于tr///中的字符序列不是正则表达式,因此您不必担心元字符。

只是为了笑

如果您希望在多个地方使用此模式,则可能希望为其指定一个带有用户定义的Unicode属性的名称。一旦它有了名字,你就可以在任何地方使用它,并且可以同时为所有人更新:

use v5.10;
my $name = "(Hello] #&^% {World[} (#@#!~`%^&()[]}{;',)!";
$name =~ s/p{IsForbidden}/_/g;
say $name;
sub IsForbidden {
# see https://perldoc.perl.org/perlunicode#User-Defined-Character-Properties
state $exclude = q|@#!~`%^&()[]}{;',|;
state $string =
join '',
map { sprintf "%Xn", ord }
split( //, $exclude );
return $string;
}


以Gene的注释为基础,指定您想要替换的内容,但我会转义每个特殊字符。注意,要替换#,请在字符数组中使用##,如第2行所示:

$name = "@ # R ! ~## ` % ^ & ( O ){{();,'`@@ { } ;!!! ' N , ";
$name =~ s/[@!~`%&^(){};',##]//g;
$name =~ s/ *//g;
print $name; 
### Outputs RON

相关内容

最新更新