2014-02-07 55 views
0

我是新来的perl,目前正试图解决一个问题。任何人都可以帮助我将不胜感激。 输入字符串由Space分隔。我需要用不同的分隔符(比如pipe'|')生成一个输出字符串,但是需要忽略双引号内的空格。在Perl中:如何更改字符串的分隔符忽略那些双引号内的字符?

例子:

 
Input String : 
Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - - 
Desired Output String : 
Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 

注:

  1. 我知道的Perl quotewords功能,但毕竟是死的慢特别是当我们需要处理数以百万计的字符串。请让我知道在这种情况下是否有任何正则表达式可以运行得更快。

  2. 不应删除双引号。需要如上所述的输出。

回答

0

这应该工作:

s='Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - -' 
perl -pe 's/ +(?=(([^"]*"){2})*[^"]*$)/|/g' <<< "$s" 
Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 

此正则表达式使用一个超前仅如果有后跟偶数引号来匹配1个或多个空格(以确保空间之外引号),并取代他们通过管道。报价必须平衡。

1

根据定界符变化'[ ]+'(一个或多个空格)' '(只有一个空格)

use Text::ParseWords; 

local $" = "|"; 
while (<DATA>) { 
    chomp; 
    my @f = quotewords('[ ]+', 1, $_); 
    print "@f\n"; 
} 

__DATA__ 
Apple Mango "Banana/Tomato [, ANYTHING INSIDE QUOTE" Grapes - "-" Pineapple - - 

输出

Apple|Mango|"Banana/Tomato [, ANYTHING INSIDE QUOTE"|Grapes|-|"-"|Pineapple|-|- 
1

写这个诡计前,这是一个有点冗长:

 
#!/usr/bin/perl 

use strict; 
use warnings; 

sub splitOutput { 
    my $sep = ' '; 
    my $output = shift; 

    my @token_array =(); 

    while ($output) { 
    if ((substr ($output, 0, 1) eq "\"") && ($output =~ m/\"([^"]*)\"$sep?/)) { 
    push (@token_array, $1); 
    $output =~ s/\"[^"]*\"$sep?//; 
    } 
    elsif ($output =~ m/([^"$sep]*)$sep?/) { 
    push (@token_array, $1); 
    $output =~ s/[^"$sep]*$sep?//; 
    } 
    } 
    return @token_array; 
} 

my $string = <STDIN>; 

my @token_array = splitOutput ($string); 

print ("$string\n"); 
print (join ('|', @token_array),"\n"); 

这将替换ev中字符串中的匹配部分重复匹配下一个带引号或不带引号的字段。请注意,如果字段之间有两个空格,则会将一个字段视为空。结果字符串也被除去了引号。

相关问题