Perl Regex:如何从"解析字符串到"没有\"?

时间:2016-03-23 11:49:24

标签: regex perl

我必须用Perl中的regex解析当前行"abc\",","\",", 得到这个结果"abc\",""\","
我这样做

while (/(\s*)/gc) {
  if (m{\G(["])([^\1]+)\1,}gc){
    say $2;
  }
}

但这是错误的,因为这个正则表达式是最后一个", 我的问题是,我怎样才能跳过这个"并停在第一个",?

4 个答案:

答案 0 :(得分:2)

以下程序根据您的规范执行匹配:

while (<>) {
    @arr = ();
    while (/("(?:\\"|[^"])*")/) {
            push @arr, $1;
            $_ = $';
    }
    print join(' ', @arr), "\n";
}

输入文件input.txt

"abc", "def"
"abc\",","\","

输出:

$ ./test.pl < input.txt
"abc" "def"
"abc\"," "\","

可以改进以更严格地匹配,因为在这种形式中可能有许多输入可能是不可取的,但它用作第一指针。此外,最好将CSV文件与相应的模块匹配,而不是使用正则表达式,但是您没有说明您的输入是否真的是CSV文件。

答案 1 :(得分:2)

不要重新发明轮子。如果您有CSV,请使用CSV解析器。

use Text::CSV_XS qw( );

my $string = '"abc\",","\","';

my $csv = Text::CSV_XS->new ({ binary => 1, auto_diag => 1 });
$csv->parse($_)
my @fields = $csv->fields();

答案 2 :(得分:1)

正则表达式不是执行此任务的最佳工具。标准Text::ParseWords模块可以轻松完成此任务。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Text::ParseWords;

my $line = '"abc\",","\","';

my @fields = parse_line(',', 1, $line);

for (0 .. $#fields) {
  say "$_: $fields[$_]"
}

输出结果为:

0: "abc\","
1: "\","

答案 3 :(得分:0)

split /(?<!\\)",(?<!\\)"/, $_

(之前用s/^"// && s/"$//;清除$ _的边界,因为包含外部引号并不需要在输入字符串的定义中,但你有它们)

直接返回你想要的数组(不需要外部循环,因为循环在核心perl函数split内,你可以根据字符串的提供方式在逗号周围添加\ s *)。

..但(实际上只是你没有提到的一个注释)可能会有更深层次的案例 如果\"表示"\\意味着\,那么您可能有\\\"\\",最后一个({1}}更常见的是,偶数\")与一行regexp复杂,因为后视是针对固定大小实现的,而不受支持的正则表达形式(?<!\\(?:\\\\)*)"也可能会很好反斜杠后没有作为来自序列\"的转义引用\\"的字符串分隔符,是不适用的,并且是一个效率较低的代码,但是这个边际考虑是关于{{1必须假设解释。