【问题标题】:perl unexpected split behaviourperl 意外的拆分行为
【发布时间】:2014-02-08 03:45:44
【问题描述】:

我正在尝试编写一个 perl 脚本,该脚本能够将我的驱动器的不同标签区分为特定的标签,然后在该特定驱动器中执行某些操作。
我在 Windows XP 计算机上运行 Active Perl 5.16.3.1603。

这是我写的:

use strict;
$_ = `fsutil fsinfo drives`;
my @drives = split;
my @labels;
for (@drives)
{
    push @labels, `label $_`;
}
for (@labels)
{
    print "$_\n";
}

最后的 for 循环是一个打印检查。
结果我什么也得不到。我试图用另一种方式检查它:

use strict;
$_ = `fsutil fsinfo drives`;

print;
print "\n";
print join "\n", split;

我的结果是:

Drives: C:\ D:\ E:\ G:\

Drives:
C:\ D:\ E:\ G:\

为什么 split 的行为不像它应该的那样?
我试着做split " "split / /split /\s+/
它们都以相同的输出结束。

如果有人知道它为什么会发生以及如何让它消失,请分享。
提前致谢。

【问题讨论】:

  • eval.in/91580 看起来不错。
  • 当我尝试手动将字符串放入 $_ 时,它起作用了。 $_ = "驱动器:C:\\D:\\E:\\G:\\"
  • fsutil fsinfo drives 的输出进行十六进制转储,以确认您得到的是实际的空格字符。
  • 这在 Windows 7 上运行良好。在命令行上试试这个perl -MData::Dumper -e"++$Data::Dumper::Useqq; print Dumper $_ = `fsutil fsinfo drives`"

标签: regex perl split


【解决方案1】:

一个 hexdump - 正如 DavidO 所建议的

00000000h: 0D 0A 44 72 69 76 65 73 3A 20 41 3A 5C 00 43 3A ; ..Drives: A:\.C:
00000010h: 5C 00 44 3A 5C 00 45 3A 5C 00 4D 3A 5C 00 0D 0A ; \.D:\.E:\.M:\...

表明您获得的(前导/尾随 CrLf)和其他(00 而不是 20)空格超出了您的预期(在 Win XP 下测试)。

所以要获得驱动器号列表,肯定正则表达式可能是更好的方法:

$ my $res = `fsutil fsinfo drives`;

Drives: A:\ C:\ D:\ E:\ M:\

$ $res =~ /\b\w:/g;
$ARRAY1 = [
            'A:',
            'C:',
            'D:',
            'E:',
            'M:'
          ];

更新评论:

  1. hexdump 为您提供二进制数据的清晰视图;我用它来展示你调用 fsutil 时真正得到的结果。
  2. 我提到了 XP,因为我不能排除 fsutil 在其他版本的 windows 上返回具有不同分隔符的字符串。
  3. 通过使用正则表达式来削减你想要的(驱动器号)而不是隐藏在两者之间的内容,我试图提出一个解决方案,即使在盖茨先生将零更改为空格、制表符或“,”时也能正常工作.
  4. 您能否提供一个链接,向外行解释“其他东西”的含义?

【讨论】:

猜你喜欢
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 2021-06-16
  • 2011-08-01
  • 2011-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多