Perl脚本实现:提取文件指定字符串间内容并保存
正确的Perl脚本实现模块定义提取
原脚本的问题
- 仅读取文件第一行:
<$fh>在标量上下文下只会读取一行内容,没有获取整个文件的全部文本 - 正则不支持多行匹配:默认正则是单行模式,
.无法匹配换行符,没法跨多行匹配到结尾的); - 匹配结果处理错误:
=~返回的是匹配成功的次数(1或0),不是实际匹配到的文本内容,直接输出会得到数字而非目标代码
解决方案脚本
# 读取源文件全部内容 open(my $in_fh, '<', 'test.v') or die "无法打开test.v: $!"; local $/; # 取消输入记录分隔符,一次性读取整个文件 my $content = <$in_fh>; close($in_fh); # 匹配从module开头到);结尾的多行内容 if ($content =~ /^module .*?\);/ms) { # 打开目标文件写入结果 open(my $out_fh, '>', 'result.v') or die "无法创建result.v: $!"; print $out_fh $&; # $& 保存最后一次正则匹配到的内容 close($out_fh); } else { die "未找到符合要求的模块定义"; }
关键说明
local $/;:临时修改Perl的输入记录分隔符为空,让<$in_fh>一次性读取整个文件到变量中- 正则修饰符
ms:m让^匹配字符串开头,s让.匹配换行符,实现跨多行匹配 .*?:非贪婪匹配,避免误匹配文件中后续可能存在的其他);$&:Perl内置变量,存储最后一次成功正则匹配到的文本内容
大文件适配版(逐行读取)
如果test.v文件体积较大,一次性读取内存占用高,可以用逐行读取的方式:
open(my $in_fh, '<', 'test.v') or die "无法打开test.v: $!"; open(my $out_fh, '>', 'result.v') or die "无法创建result.v: $!"; my $in_module = 0; while (my $line = <$in_fh>) { if (!$in_module && $line =~ /^module/) { $in_module = 1; } if ($in_module) { print $out_fh $line; if ($line =~ /\);/) { last; # 找到结束标记就停止读取 } } } close($in_fh); close($out_fh);
内容的提问来源于stack exchange,提问作者vikas
相关产品推荐
相关产品推荐

