1

我有以下格式化的示例字符串:

== header == information about things ==headeragain== info can have characters like.*?{=

等仅在一行上。

我想将其解析为哈希,使得键是“==.+?==”,值是键之后的信息。我尝试了几个正则表达式来全局匹配这些对:

%hash = $string =~ /(==.+?==)(.+)/g

%hash = $string =~ /(==.+?==)(.+?)/g

将匹配第一个键,然后将其他所有内容作为其值,并分别仅匹配键。

%hash = $string =~ /(==.+?==)(.+(?===.+?==))/g

应该向前看下一个键,但不是我理解的“吃掉它”。但是,它只会匹配第一对而不会进一步。

我认为这个问题来自对全局修饰符如何起作用的误解。我需要在我的一种表达方式中进行一些调整吗?还是我需要做一些完全不同的事情?

4

2 回答 2

1

即使您使用的是非贪婪修饰符,第二个示例中的第二个子组也没有限制。

添加积极的前瞻性:(?=$|==)价值之后。这(?=是前瞻块的声明,$或者==是您正在搜索的子字符串。

即解决方案是:/(==.+?==)(.+?)(?=$|==)/g

于 2012-04-07T20:33:57.683 回答
1
while ($line =~ /
   == \s*
   ( .+? )
   \s* == \s*
   ( .*? )
   (?= \s* (?: == | \z ) )
/xg) {
   my $key = $1;
   my $val = $2;
   ...
}

但我不喜欢使用“ ?”量词修饰符。当给出错误或意外的输入时,它实际上并不能防止匹配错误的东西。所以我会使用:

while ($line =~ /
   == \s*
   ( \S (?: (?! \s* == ). )* )
   \s* == \s*
   ( (?: (?! \s* == ). )* )
/xg) {
   my $key = $1;
   my $val = $2;
   ...
}
于 2012-04-07T20:42:22.647 回答