【问题标题】:How can I suppress empty leading fields in Perl's split()?如何抑制 Perl 的 split() 中的空前导字段?
【发布时间】:2009-09-28 02:12:48
【问题描述】:

splitperlfunc 条目说:

默认情况下,保留空的前导字段

暗示有一种方法可以覆盖该默认值,但后来它说的是:

当字符串开头存在正宽度匹配时,会产生空前导字段

...这是否意味着无法跳过第一个字段?

这不是关键任务,但我在斜杠上拆分一个根相对 URL,比如 /foo/bar/,然后得到

['', 'foo', 'bar']

想知道是否有办法得到那个空白的第一项。

【问题讨论】:

  • 您在文档中遗漏了下一句:(如果所有字段均为空,则它们被视为尾随。)您认为这是提示的例外。
  • 啊,这至少解释了我的困惑。
  • @brian:既然如此,我认为这句话令人困惑。它应该说“一般”,而不是“默认”。 “默认情况下”意味着可以通过指定可选参数或其他配置以某种方式更改行为,而不是根据 split() 操作的数据(甚至在运行之前可能不知道) -时间)。我认为这种混淆是由于“默认”这个短语的简单英语用法与“默认”这个词的特殊计算机科学用法之间的差异造成的。

标签: perl split


【解决方案1】:

如果您想拆分路径元素,请查看 File::SpecPath::Class,它们处理所有操作系统特定的内容:

 use File::Spec;

 my( $root, @path_parts ) = File::Spec->splitdir( $path );

保留根的好处是您可以轻松地向后退,并且仍然保留前导斜杠(或您的操作系统可能使用的任何东西):

 my $path = File::Spec->catfile( $root, @path_parts );

这对 URL 来说没什么大不了的,因为它们都使用类似 unix 的路径规范。尽管如此,以同样的方式构建本地路径很容易,并且记住根在哪里(这在 Windows、VMS 等上可能很重要):

 my ($docroot_root, @doc_root ) = File::Spec->splitdir( $ENV{DOCUMENT_ROOT} );
 my $local_path = File::Spec->catfile( $docroot_root, @doc_root, @path_parts );

否则,您会被 split 的作用所困扰。它假定您关心字段的位置,因此它会保留它们的位置(即第一个分隔符之前的东西在列表中始终是位置 0,即使它是空的)。对于您的问题,我倾向于将其写为一个列表赋值,在其中我使用一个变量来吸收初始的空字段,就像我对

所做的那样
 my( $root, @path_parts ) = split m|/|, $path;

【讨论】:

  • 很明显,splitdir 可以在 Unixy 系统和 Windows 上运行,但在其他平台上也能正常运行吗?
  • 它应该也可以在其他平台上工作。这才是重点。如果您正在讨论它决定使用哪个子类,您可能需要在那里做一些魔术。
【解决方案2】:

您可以使用 grep 删除任何长度为零的字段。

grep (length, split ('/','/foo/bar'))

我不认为 split 可以自己做你想做的事。

告诉您使用特定领域的功能进行拆分的人是正确的。特定领域的拆分等效项将自动为您处理各种非显而易见的特殊情况。

【讨论】:

  • 这有可能从中间删除元素的奇怪效果。无论如何,您可能都想摆脱这些,但有时您可能不想。
【解决方案3】:

brian d foy mentioned File::Spec 模块。我真的很喜欢这个,因为它采用直观的方法,并且您确切地知道自己得到了什么。

根据您使用 Perl 的脚本/编程风格,您可能想尝试一下:

($volume, $directories, $file) = File::Spec->splitpath( $path );

结果很简单,例如,如果您需要音量,它就在您的指尖!

它使您的代码更具可读性!请注意,不同的模块有不同的规范,例如符号链接或挂载的磁盘。

【讨论】:

  • 这可能不适合拆分通用案例 URL。如果您直接使用 Linux 文件路径,我会推荐它。
  • 你觉得 URL 路径和 linux 文件路径有什么不同?
  • 不,你是对的,没有什么不同。我在想您是否正在解析不是特定于您的服务器的路径。但就像你说的,URL 都将遵循相同的结构,所以这不会是一个问题。谢谢!
【解决方案4】:

您可以使用的一种方法是使用正则表达式来删除任何前导分隔符。

例如

$str = "/foo/bar"; $str =~ m!^/*!!;

然后像以前一样进行拆分。

【讨论】:

    【解决方案5】:

    split(' ', $string) 会将字符串拆分为空格,但不会为您提供前导、尾随或内部空字段。

    我认为这是一个更一般的情况,但在 'x' 上进行拆分等同于 /x/

    【讨论】:

      【解决方案6】:

      喜欢这个

      (undef,@x)= split /\//,$string;
      

      【讨论】:

      • 如果字符串前面没有分隔符,那不是去掉第一个合法元素吗?
      • (undef,@x)=split m'/', $string;
      【解决方案7】:

      如果您通过“/”的分隔符进行拆分,那么我发现输出没有任何问题。考虑到第一个字符是分隔符,那么它别无选择,只能有一个空字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-07
        • 2011-10-15
        相关资源
        最近更新 更多