`s/"((?:[^"]|\")*)"//` 在 Perl 中解析 C 字符串有什么问题?

问题描述 投票:0回答:1

看来我正坐在我的眼睛上,因为我无法找出我的正则表达式有什么问题:

我正在尝试解析一个在一行中包含字符串的 C 源文件(实际上这些字符串是正则表达式,但这并不重要)。 基本上

/"([^"]*)"/
应该捕获字符串(不带引号),除非其中有双引号。

我也可以使用

/(\\"*)/!
匹配字符串中的双引号,但我未能组合两个正则表达式:

使用

/"((?:[^"]|\\")*)"/
(捕获双引号之间的文本,直到第一个非转义双引号)捕获在第一个
"
之后结束,如本示例调试器会话所示:

  DB<15> $x='"SAMSUNG SSD SM841N? (2\\.5\"? 7mm |mSATA )?(128|256|512)GB( SED)?|"'

  DB<16> x $x =~ s/"((?:[^"]|\\")*)"//
0  1
  DB<17> x $x
0  '? 7mm |mSATA )?(128|256|512)GB( SED)?|"'
  DB<18>

在写这个问题时,我尝试交换两种选择,突然它起作用了:

  DB<18> $x='"SAMSUNG SSD SM841N? (2\\.5\"? 7mm |mSATA )?(128|256|512)GB( SED)?|"'

  DB<19> x $x =~ s/"((?:\\"|[^"])*)"//
0  1
  DB<20> x $x
0  ''
  DB<21>

那么正则表达式

A|B
B|A
不是等价的吗?

regex string perl double-quotes
1个回答
0
投票

当我在写问题时找到答案时,我本可以取消提问,但因为我认为这对其他人来说也可能很有趣,所以我将在这里提供我的答案:

来自 man perlre(1):

从左到右尝试替代方案,因此找到的第一个与整个表达式匹配的替代方案就是被选择的方案。这意味着替代方案不一定是贪婪的。例如:当将“foo|foot”与“barefoot”匹配时,只有“foo”部分会匹配,因为这是尝试的第一个替代方案,并且它成功匹配目标字符串。 (这可能看起来并不重要,但是当您使用括号捕获匹配的文本时,它很重要。)

所以实际上是的,替代品的顺序很重要。

© www.soinside.com 2019 - 2024. All rights reserved.