【发布时间】:2011-01-28 10:03:46
【问题描述】:
我正在寻找一种解决方案来拆分包含以下格式文本的字符串:
"abcd efgh 'ijklm no pqrs' tuv"
这将产生以下结果:
['abcd', 'efgh', 'ijklm no pqrs', 'tuv']
换句话说,除非在单引号字符串内,否则它会按空格分割。我认为这可以通过使用“环视”运算符的 .NET 正则表达式来完成,尤其是平衡运算符。我不太确定 Perl。
【问题讨论】:
我正在寻找一种解决方案来拆分包含以下格式文本的字符串:
"abcd efgh 'ijklm no pqrs' tuv"
这将产生以下结果:
['abcd', 'efgh', 'ijklm no pqrs', 'tuv']
换句话说,除非在单引号字符串内,否则它会按空格分割。我认为这可以通过使用“环视”运算符的 .NET 正则表达式来完成,尤其是平衡运算符。我不太确定 Perl。
【问题讨论】:
#!/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 的源代码以查看使用的模式。
【讨论】:
Text::ParseWords 是核心。此外,具有巨大依赖列表的模块或发行版并不常见。
所以您决定使用正则表达式?现在你有两个问题。
请允许我稍微推断一下。您需要任意数量的字段,其中字段由不包含空格的文本组成,或者由空格分隔并以引号开头并以引号结尾(可能中间有空格)。
换句话说,你想做命令行 shell 所做的事情。你真的应该重用一些东西。如果做不到这一点,您应该一次捕获一个字段,使用正则表达式:
^ *([^ ]+|'[^']*')(.*)
将第一组添加到列表中,然后使用第二组的内容继续循环。
单次通过正则表达式将无法捕获任意大量的字段。您也许可以在正则表达式上进行拆分(python 会这样做,不确定 perl),但由于您要匹配空格之外的内容,所以我不确定这是否是一个选项。
【讨论】:
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;
【讨论】: