Perl:正则表达式在重复模式之间获取所有文本

Coc*_*oco 4 regex perl parsing regexp-grammars

我想为以下内容创建一个正则表达式.

我有一些如下文字:

field = "test string";
type =  INT;
funcCall(.., field, ...);
...
text = "desc";

field = "test string 1";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 2";

field = "test string 2";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 3";

.... keeps repeating
Run Code Online (Sandbox Code Playgroud)

基本上我正在尝试创建一个正则表达式,它将从第一个"field ="的开头到第二个"field ="的开头获取所有文本.它必须跳过函数调用中使用的字段文本.

我目前有以下内容:

my @overall = ($string =~ m/field\s*=.*?/gis);
Run Code Online (Sandbox Code Playgroud)

但是,这只是获得文本"field =".没有"?" 它从第一个到最后一个实例获取所有数据.

我也尝试过:

my @overall = ($string =~ m/field\s*=.*field\s*=/gis);
Run Code Online (Sandbox Code Playgroud)

然而,这将使我得到所有其他实例,因为它占有第二个"field ="字符串.有什么建议?

Axe*_*man 5

我可以看到这样做的最简单方法是split$string/^\s*field\s*=/表达.如果我们想要捕获'field = '文本的一部分,我们可以打破前瞻:

foreach ( split /(?=^\s*field\s*=)/ms, $string ) {
    say "\$_=[\n$_]";
}
Run Code Online (Sandbox Code Playgroud)

因此,它在每一行的开头处断开,其中'field'是下一个非空白字符串,后跟任意数量的空格,后跟一个'='.

输出是:

$_=[
field = "test string";
type =  INT;
funcCall(.., field, ...);
...
text = "desc";
]
$_=[

]
$_=[
field = "test string 1";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 2";
]
$_=[

]
$_=[
field = "test string 2";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 3";

.... keeps repeating
]
Run Code Online (Sandbox Code Playgroud)

几乎我想要的.但是,它会在我们想要的捕获之间留下一个空白线.我不知道如何摆脱它,所以我们只是过滤掉所有的空白字符串:

foreach ( grep { m/\S/ } split /(?=^\s*field\s*=)/ms, $string ) {
    say "\$_=[\n$_]";
}
Run Code Online (Sandbox Code Playgroud)

然后它产生:

$_=[
field = "test string";
type =  INT;
funcCall(.., field, ...);
...
text = "desc";
]
$_=[
field = "test string 1";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 2";
]
$_=[
field = "test string 2";
type = FLOAT;
funcCall(.., field, ...);
...
text = "desc 3";

.... keeps repeating
]
Run Code Online (Sandbox Code Playgroud)

你可以使用哪个.


Sob*_*que 0

这对于正则表达式来说很难。幸运的是,这不是你盒子里唯一的工具。

看起来每条记录之间都有一个空行。如果是这样,您可以通过设置为 轻松完成此$/操作"\n\n"。然后,您可以使用 while 循环读取文件,并且每次迭代都$_将设置为您尝试处理的块。

如果做不到这一点,您可以将其设置为field =或者甚至只是使用split