假设以下字符串中的PORTION表示正则表达式需要捕获的部分

,"PORTION","","a",["some_string"]

部分的例子是
  • \“abc123
  • abc123 \“
  • \“abc123 \”
  • abc \“123 \”
  • abc123

  • 所以字符串实际上看起来像
  • ,“\” abc123“,”“,” a“,[” some_string“]
  • ,“abc123 \”“,”“,” a“,[” some_string“]
  • “\” abc123 \“”,“”,“a”,[“some_string”]
  • “abc \” 123 \“”,“”,“a”,[“some_string”]
  • “abc123”,“”,“a”,[“some_string”]

  • 部分用双引号引起来。 PORTION中的双引号由反斜杠转义。我目前的模式是
    my $pattern = '(.?([\\"]|[^"][^,][^"])*)';
    

    产生上述示例的结果如下
  • \“abc123”,“”,“a”
  • abc123
  • \“abc12
  • abc \“123 \”“
  • abc123“

  • 模式尝试匹配序列中不是“,”的所有内容
    并允许捕获\“
    但它没有按预期工作。
    我该如何运作?

    最佳答案

    您使它变得太复杂了;没有规则说您必须在一个整体正则表达式中进行所有解析。由于您的字符串看起来像是逗号分隔的序列,因此请首先将其解析为:

    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/

    10-13 00:51