无法获得正确的匹配开始和结束偏移

时间:2012-11-07 13:39:14

标签: regex perl

我有一个正则表达式如下:

$regex = qr/(?sx-im:(?sx-im:(?:^|(?<=\n)))(?=(?sx-im:[\ \t]*)(?sx-im:(?:^|(?<=\n))Data\ and\ value)(?sx-im:[\ \t\r]*(?:$|\n))))/;

我将其与以下文字进行匹配:

$text ="Data and value";

现在我想获得匹配开始偏移量,匹配结束偏移量和匹配文本。

通常我使用@-@+$&来获取以下内容:

if($text  =~ m/$regex/) 
{
        print "START Offset = ".$-[0];
        print "END Offsset  = ".$+[0];
        print "Matched Text = ".$&;
}

在这种情况下,匹配成功,但我无法获得正确的偏移量和匹配的文字。它只是打印0作为匹配开始偏移量和匹配结束偏移量。并且它的打印空为匹配文本。

我想了解这个正则表达式的不同组件。具体是(?sx-im:是什么,如何获得匹配的文字

请不要问我这样的正则表达式的原因或建议我改变正则表达式。这是一个软件生成的正则表达式。为了提问,我简化了我的问题。

请指导我从哪里开始了解此正则表达式并获得匹配偏移量。

2 个答案:

答案 0 :(得分:4)

(?: ... )是一个非捕获组。它不会创建反向引用。

类似地,(?= ... )是零宽度前瞻断言。它不包含匹配的字符串$&

请参阅Extended Patterns

答案 1 :(得分:4)

错误在你的正则表达式中,而不是你对匹配偏移的理解。它匹配字符串开头的零宽度字符串,并正确报告0的开始和结束偏移。

现在为什么匹配这是另一个好问题。你可以拆分正则表达式(未经测试):

qr/(?sx-im:
  (?sx-im:(?:^|(?<=\n)))
  (?=(?sx-im:[\ \t]*)(?sx-im:(?:^|(?<=\n))Data\ and\ value)(?sx-im:[\ \t\r]*(?:$|\n)))
)/x

你可以看到它的两个连续的一半:

  • 第一个匹配行的开头或\n的后向匹配 - 即两者都是零宽度。
  • 第二个是一堆东西的前瞻性匹配,但同样是零宽度匹配。

你似乎试图用正则表达式做太多,特别是匹配行的开头和结尾。考虑逐行读取源文件并处理单独的行,而不是尝试使用正则表达式完成所有操作。