假设需要由正则表达式捕获的部分由以下字符串中的PORTION指示
,"PORTION","","a",["some_string"]
PORTION的例子是
所以字符串实际上看起来像
PORTION被双引号括起来。 PORTION中的双引号由反斜杠转义。我目前的模式是
my $pattern = '(.?([\\"]|[^"][^,][^"])*)';
产生上述例子的结果如下
模式尝试匹配不是“,”的序列前面的所有内容 并且还允许捕获\“ 但它没有按预期工作。 我怎样才能使它发挥作用?
答案 0 :(得分:5)
你太复杂了;没有规则说你必须在一个单片正则表达式中进行所有解析。由于您的字符串看起来像逗号分隔的序列,因此首先将其解析为:
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。
答案 1 :(得分:3)
只需使用Text::CSV
即可答案 2 :(得分:1)
您的问题需要臭名昭着的零宽度负面后卫断言
...可让您匹配不关注foo
的{{1}}。
文档在这里:http://perldoc.perl.org/perlre.html#Extended-Patterns
你想在你的正则表达式中使用这样的东西:
bar
匹配双引号,尽可能少的任何字符,然后另一个双引号前面没有反斜杠(我认为通过加倍逃脱)。第一组parens按照你的意图捕获,第二个括号没有捕获。
修改:同时使用http://www.internetofficer.com/seo-tool/regex-tester/进行测试 它似乎工作正常。
编辑:正如outis指出的那样,此表达式将无法正确匹配一个PORTION,其中结束引号之前的最后一个字符是转义反斜杠。如果您没有预料到文本中的反斜杠,那么您应该没问题。
答案 3 :(得分:1)
不要忘记允许转义的反斜杠和转义引号。使用RE匹配平衡的任何东西都会变得很难看:
/(?<=")((?:[^"\\]+|\\+[^"\\]|(?:\\\\)+|(?<!\\)\\(?:\\\\)*")*)(?=")/
像以太一样,帮自己一个忙,并使用解析器。
答案 4 :(得分:0)
如果您的数据以逗号分隔并且没有嵌入的逗号,只需拆分“,”并获取相应的字段
while(<>){
chomp;
@s = split /,/;
if ($s[0] eq ""){
print "$s[1]\n";
}else{
print $s[0]."\n";
}
}
输出
$ perl perl.pl file
"\"abc123"
"abc123\" "
"\"abc123\""
"abc\"123\""
"abc123"
答案 5 :(得分:0)
如果你需要考虑outis提到的转义反斜杠,你可以使用:
m/"((\\\\|\\"|[^"])+)"/
(似乎我不能对outis的答案发表评论,但outis解决方案不适用于此:
"abc\\\"123"
将产生
abc\\\
)
输入:
,"\"abc123","","a",["some_string"] ,"abc123\" ","","a",["some_string"] "\"abc123\"","","a",["some_string"] "abc\"123\"","","a",["some_string"] "abc123","","a",["some_string"] "ab\\c123","","a",["some_string"] "abc123\\","","a",["some_string"] "abc123\\\"","","a",["some_string"] "abc\\\"123\"","","a",["some_string"] "abc123\\\\\"","","a",["some_string"]
输出:
\"abc123 abc123\" \"abc123\" abc\"123\" abc123 ab\\c123 abc123\\ abc123\\\" abc\\\"123\" abc123\\\\\"