所以,我在另一篇文章中看到要使用\\
作为分隔符进行拆分,您需要拆分\\\\\\\\
。这对我来说没有意义,但是当我尝试使用\\\\
进行拆分时,发生了这种情况:
my $string="a\\\\b\\\\c";
my @ra=split("\\\\",$string);
数组是:
a
<empty>
b
<empty>
c
正如另一张海报所说,使用\\\\\\\\
完美无缺。为什么会这样?
此外,我很好奇并开始搞砸''
vs ""
,并得到了意想不到的结果。我以为我明白了区别是什么,但我想我没有,至少在以下情况下没有:
my $string="a\.\.b\.\.c";
my @ra=split("\.\.",$string);
数组是:
<empty>
<empty>
<empty>
c
然而,
my $string="a\.\.b\.\.c";
my @ra=split('\.\.',$string);
数组是:
a
b
c
提前致谢。
答案 0 :(得分:4)
哦,引用规则和正则表达式。
在q()
及相关内容中,所有反斜杠都保留在字符串中,除非它们转义字符串分隔符或其他反斜杠:
say '\a\\b\''; # »\a\b'«
在qq()
及相关内容中,所有不构成已知字符串转义序列的反斜杠都会被静默删除:
say "\d\\b\"\."; # »d\b."«
在qr//
和正则表达式文字中同上,但与双引号字符串相比有不同的转义。
如果使用字符串代替正则表达式,那么在编译期间将执行该类型字符串的转义规则。但是,当它用作正则表达式时会处理第二级转义,因此在最坏的情况下反斜杠必须双重转义。正则表达式文字没有遭受这个问题;只有一个级别的逃脱。
因此,"a\\\\b\\\\c";
为a\\b\\c
,"\\\\"
为\\
,其中\
与正则表达式匹配。因此它会在每个反斜杠上分割,从而在双反斜杠之间生成零长度字段。
您所指的其他问题的'\\\\\\\\'
是\\\\
,正则表达式与\\
匹配。
"a\.\.b\.\.c"
为a..b..c
,"\.\."
为..
,正则表达式匹配两个非换行符。它首先匹配a.
,然后匹配.b
,然后匹配..
。这会生成字符串片段"", "", "", "c"
。
字符串'\.\.'
为\.\.
,正则表达式依次匹配两个文字句点。
解决方案是使用regex到期的正则表达式。 split
将正则表达式作为第一个参数(如split /foo/
),在其他方案中,正则表达式引用qr/foo/
很有用。这避免了令人费解的 [1] 双重逃逸。
[1]:对于“心灵弯曲”的小值,一旦你遵守规则。
答案 1 :(得分:3)
在单引号字符串文字中,
\
后跟字符串分隔符(默认情况下为'
)会产生字符串分隔符。
'That\'s fool\'s gold!' -> That's fool's gold!
q!That's fool's gold\!! -> That's fool's gold!
\
后跟\
会产生\
。
'c:\\foo' -> c:\foo
\
后跟任何其他内容会产生这两个字符。
'c:\foo' -> c:\foo
在双引号字符串文字中,
\
后跟该字符的非单词字符结果。
"c:\\foo" -> c:\foo
"Can't open \"foo\"" -> Can't open "foo"
\
后跟单词字符具有特殊含义。
"foo\n" -> foo{newline}
在正则表达式文字中,
\
后面的分隔符被替换为分隔符中的结果。
qr/\// -> /
\
后跟任何其他内容会产生这两个字符。
qr/\\/ -> \\
qr/\_/ -> \_
qr/\$/ -> \$
qr/\n/ -> \n
应用正则表达式时,
\
后跟非字符字符匹配该字符。
/c:\\foo/ -> Matches strings containing: c:\foo
\
后跟单词字符具有特殊含义。
/foo\z/ -> Matches strings ending with: foo
查看你的案例:
my $string="a\\\\b\\\\c";
my @ra=split("\\\\",$string);
"\\\\"
会生成字符串\\
,因此您首先创建字符串a\\b\\c
,然后将\\
传递给split
。
split
的第一个参数用作正则表达式,正则表达式模式\\
匹配单个\
。 \
中有4个a\\b\\c
,因此它会分成4 + 1个。
如果使用正则表达式文字而不是双引号字符串文字,则会减少混淆。
split(/\\/, $string); # Passes pattern \\ to split. Matches singles
split("\\\\", $string); # Passes pattern \\ to split. Matches singles
split(/\\\\/, $string); # Passes pattern \\\\ to split. Matches doubles
split("\\\\\\\\", $string); # Passes pattern \\\\ to split. Matches doubles
简而言之,请勿使用split "..."
!
现在你的其他两个案子应该是显而易见的。
my $string="a\.\.b\.\.c"; # String a..b..c
my @ra=split("\.\.",$string); # Pattern .., which matches any two chars.
my $string="a\.\.b\.\.c"; # String a..b..c
my @ra=split('\.\.',$string); # Pattern \.\., which matches two periods.
答案 2 :(得分:0)
使用/ \\\\ /而不是“\\\\”进行拆分,避免一切后顾之忧,
e.g。
use Data::Dumper;
my $string= "a\\\\b\\\\c";
my @ra = split /\\\\/, $string;
print Dumper @ra;
将输出
$VAR1 = [
'a',
'b',
'c'
];
/ \\ /将连续匹配两个\
或者你可以很可爱并且做到
split /\\{2}/, $string