如何在不拆分单引号字符串的情况下通过空格拆分字符串?

6
我是一个帮助翻译的助手。以下是你需要翻译的内容:

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

"abcd efgh 'ijklm no pqrs' tuv"

以下是产生的结果:
['abcd', 'efgh', 'ijklm no pqrs', 'tuv']

换言之,它会按空格进行分割,除非在单引号字符串内。我认为可以使用 .NET 正则表达式来实现,特别是平衡运算符中的“环视”操作符。关于 Perl,我不太确定。
3个回答

15

使用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 = [
          'abcd',
          'efgh',
          'ijklm no pqrs',
          'tuv'
        ];

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


5
归咎于那些优秀的人们吧,当他们找不到自己需要的东西时,就得自己写出来,最后把结果上传到CPAN上。 :) - hobbs
@zan,顺带一提,Text::ParseWords是内核的一部分。此外,拥有巨大依赖项列表的模块或分发包并不常见。 - Sinan Ünür

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;

你应该稍微解释一下程序。 - U. Windl

1

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

让我推断一下。你想要任意数量的字段,其中一个字段由不包含空格的文本组成,或者由用引号括起来并以引号结尾的空格分隔的文本组成(中间可能有空格)。

换句话说,你想做的就是命令行 shell 所做的事情。你真的应该重用一些东西。如果失败了,你应该逐个捕获字段,使用类似于以下的正则表达式:

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

在将第一组附加到列表中并使用第二组的内容继续循环时。

单次正则表达式匹配无法捕获任意数量的字段。您可能能够在正则表达式上进行拆分(Python 可以做到这一点,不确定 Perl 是否可以),但由于您正在匹配空格外的内容,因此我不确定这甚至是一个选项。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接