gpt4 book ai didi

perl - 使用 $INPUT_RECORD_SEPARATOR 作为正则表达式读取 perl 文件句柄

转载 作者:行者123 更新时间:2023-12-04 21:08:43 24 4
gpt4 key购买 nike

我正在寻找一种方法来逐行读取文件句柄(然后在每一行上执行一个函数),具有以下扭曲:我想视为“行”的内容应以不同的字符终止,而不仅仅是我定义为 $/ 的单个字符.我现在 $INPUT_RECORD_SEPARATOR$/不支持正则表达式或传递要视为行终止符的字符列表,这就是我的问题所在。

我的文件句柄来自一个进程的标准输出。因此,我无法在文件句柄内查找,并且无法立即获得全部内容,而是在执行过程时一点一点生成。我希望能够使用我称为 handler 的函数将时间戳之类的内容附加到该过程产生的每个“行”。在我的例子中。每一行都应在程序生成后立即处理。

不幸的是,我只能想出一种方法来执行 handler立即运行,但似乎非常低效或使用缓冲区但只会导致 handler 的“分组”调用的方式函数,因此,例如,产生错误的时间戳。

事实上,在我的具体情况下,我的正则表达式甚至会非常简单,只需阅读 /\n|\r/ .因此,对于这个特殊问题,我什至不需要完整的正则表达式支持,只需将多个字符视为行终止符即可。但是$/不支持这个。

在 Perl 中有解决这个问题的有效方法吗?

这是一些快速的伪 perl 代码来演示我的两种方法:

逐字节读取输入文件句柄

这看起来像这样:

my $acc = "";
while (read($fd, my $b, 1)) {
$acc .= $b;
if ($acc =~ /someregex$/) {
handler($acc);
$acc = "";
}
}

这里的优点是, handler一旦读取了足够的字节,就会立即分派(dispatch)。缺点是,我们对从 $fd 读取的每个字节进行字符串附加并检查正则表达式。 .

一次读取带有 X 字节 block 的输入文件句柄

这看起来像这样:
my $acc = "";
while (read($fd, my $b, $bufsize)) {
if ($b =~ /someregex/) {
my @parts = split /someregex/, $b;
# for brevity lets assume we always get more than 2 parts...
my $first = shift @parts;
handler(acc . $first);
my $last = pop @parts;
foreach my $part (@parts) {
handler($part);
}
$acc = $last;
}
}

这里的优点是,我们更高效,因为我们只检查每个 $bufsize字节。缺点是, handler 的执行必须等到 $bufsize字节已被读取。

最佳答案

将 $INPUT_RECORD_SEPARATOR 设置为正则表达式不会有帮助,因为 Perl 的 readline也使用缓冲 IO。诀窍是使用您的第二种方法,但使用无缓冲 sysread而不是 read .如果您 sysread从管道中,调用将在数据可用时立即返回,即使无法填充整个缓冲区(至少在 Unix 上)。

关于perl - 使用 $INPUT_RECORD_SEPARATOR 作为正则表达式读取 perl 文件句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39657095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com