全局匹配的名称值对,它们之间没有分隔符

时间:2012-04-07 20:01:19

标签: regex perl key-value

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

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

等只有一行。

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

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

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

将匹配第一个键,然后匹配其他所有值,并分别匹配键。

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

应该向前看下一把钥匙,但不要"吃掉它#34;据我了解。但是,它只会匹配第一对而不再进一步。

我认为这个问题来自对全局修饰语行为的误解。我是否需要在我的某个表达式中调整某些内容?或者我需要做一些完全不同的事情吗?

2 个答案:

答案 0 :(得分:1)

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

在值之后添加正面预测:(?=$|==)。此处(?=是预读块的声明,$==是您正在搜索的子字符串。

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

答案 1 :(得分: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;
   ...
}