假设以下字符串中的PORTION表示正则表达式需要捕获的部分
,"PORTION","","a",["some_string"]
部分的例子是
所以字符串实际上看起来像
部分用双引号引起来。 PORTION中的双引号由反斜杠转义。我目前的模式是
my $pattern = '(.?([\\"]|[^"][^,][^"])*)';
产生上述示例的结果如下
模式尝试匹配序列中不是“,”的所有内容
并允许捕获\“
但它没有按预期工作。
我该如何运作?
最佳答案
您使它变得太复杂了;没有规则说您必须在一个整体正则表达式中进行所有解析。由于您的字符串看起来像是逗号分隔的序列,因此请首先将其解析为:
my @fields = split /(?<!\\),/, $string; # use comma as a delimiter (except when escaped)
...然后相应地解析您的第一个字段:
shift @fields unless $fields[0]; # pull off the potentially null first field
$fields[0] =~ s/^"//g; # remove the leading "
$fields[0] =~ s/(?<!\\)"$//g; # remove the trailing " that isn't preceded by a \
您可以通过将以上代码包装在for循环或map()中,以这种方式解析所有字段。
请注意,此代码无法解决诸如
\\,
这样的情况(逗号在此处是有效的定界符,即使它会错误地通过正则表达式也是如此)。因此,最好使用适合于您的格式的解析器(无论它是什么格式)。您可能想看看Text::CSV。关于regex - 我如何捕获一个逃脱的人,而不是一个逃脱的人?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2175022/