【问题标题】:How can I split a string by whitespace unless inside of a single quoted string?除非在单引号字符串内,否则如何按空格分割字符串?
【发布时间】:2011-01-28 10:03:46
【问题描述】:

我正在寻找一种解决方案来拆分包含以下格式文本的字符串:

"abcd efgh 'ijklm no pqrs' tuv"

这将产生以下结果:

['abcd', 'efgh', 'ijklm no pqrs', 'tuv']

换句话说,除非在单引号字符串内,否则它会按空格分割。我认为这可以通过使用“环视”运算符的 .NET 正则表达式来完成,尤其是平衡运算符。我不太确定 Perl。

【问题讨论】:

    标签: regex perl split


    【解决方案1】:

    使用Text::ParseWords:

    #!/usr/bin/perl
    
    use strict; use warnings;
    use Text::ParseWords;
    
    my @words = parse_line('\s+', 0, "abcd efgh 'ijklm no pqrs' tuv");
    
    use Data::Dumper;
    print Dumper \@words;
    

    输出:

    C:\Temp> ff
    $VAR1 = [
              'A B C D',
              'efgh',
              'ijklm 没有 pqrs',
              “电视”
            ];

    您可以查看Text::ParseWords::parse_line 的源代码以查看使用的模式。

    【讨论】:

    • @Jergason 将其归咎于优秀的人,当他们没有找到他们需要的确切内容并且必须自己编写时,CPAN 之后的结果。 :)
    • @zan FWIW, Text::ParseWords 是核心。此外,具有巨大依赖列表的模块或发行版并不常见。
    【解决方案2】:

    所以您决定使用正则表达式?现在你有两个问题。

    请允许我稍微推断一下。您需要任意数量的字段,其中字段由不包含空格的文本组成,或者由空格分隔并以引号开头并以引号结尾(可能中间有空格)。

    换句话说,你想做命令行 shell 所做的事情。你真的应该重用一些东西。如果做不到这一点,您应该一次捕获一个字段,使用正则表达式:

    ^ *([^ ]+|'[^']*')(.*)
    

    将第一组添加到列表中,然后使用第二组的内容继续循环。

    单次通过正则表达式将无法捕获任意大量的字段。您也许可以在正则表达式上进行拆分(python 会这样做,不确定 perl),但由于您要匹配空格之外的内容,所以我不确定这是否是一个选项。

    【讨论】:

      【解决方案3】:
      use strict; use warnings;
      
      my $text = "abcd efgh 'ijklm no pqrs' tuv 'xwyz 1234 9999' 'blah'";
      my @out;
      
      my @parts = split /'/, $text;
      
      for ( my $i = 1; $i < $#parts; $i += 2 ) {
          push @out, split( /\s+/, $parts[$i - 1] ), $parts[$i];
      }
      
      push @out, $parts[-1];
      
      use Data::Dumper;
      print Dumper \@out;
      

      【讨论】:

      • 你应该解释一下程序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-17
      • 1970-01-01
      • 1970-01-01
      • 2012-08-03
      • 2016-01-07
      • 1970-01-01
      相关资源
      最近更新 更多