在Perl中:如何更改字符串的分隔符,忽略双引号内的分隔符?

时间:2014-02-07 06:22:23

标签: regex string perl delimiter

我是perl的新手,目前正试图解决一个问题。任何可以帮助我的人都将不胜感激。 输入字符串由Space分隔。我需要生成一个带有不同分隔符的输出字符串(比如管道'|'),但需要忽略双引号内的空格。

示例:

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 引用词函数,但是当我们需要处理数百万字符串时,这种情况已经很慢了。如果在这种情况下有任何可以更快运行的正则表达式,请告诉我。

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

3 个答案:

答案 0 :(得分: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 :(得分: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");

这将替换匹配下一个引用或未引用字段的每次迭代中字符串中的匹配部分。请注意,如果字段之间有两个空格,则会将一个字段视为空。结果字符串也删除了引号。

答案 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个或多个空格,前提是后跟偶数引号(以确保空格在引号外)并用管道替换它们。报价必须平衡。