我有以下格式化的示例字符串:
== header == information about things ==headeragain== info can have characters like.*?{=
等只有一行。
我想将其解析为哈希,使得键是" ==。+?=="并且值是键后的信息。我尝试了几个正则表达式来全局匹配这些对:
%hash = $string =~ /(==.+?==)(.+)/g
和
%hash = $string =~ /(==.+?==)(.+?)/g
将匹配第一个键,然后匹配其他所有值,并分别匹配键。
%hash = $string =~ /(==.+?==)(.+(?===.+?==))/g
应该向前看下一把钥匙,但不要"吃掉它#34;据我了解。但是,它只会匹配第一对而不再进一步。
我认为这个问题来自对全局修饰语行为的误解。我是否需要在我的某个表达式中调整某些内容?或者我需要做一些完全不同的事情吗?
答案 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;
...
}