[英]Perl Regex match works, but replace does not
我整理了一个Perl脚本来遍历目录,并匹配源代码中的各种键,然后将结果输出到文本文件中。 匹配操作效果很好,但是最终目标是执行替换操作。 Perl脚本如下:
#!/usr/bin/perl
#use strict;
use warnings;
#use File::Slurp;
#declare variables
my $file = '';
my $verbose = 0;
my $logfile;
my @files = grep {/[.](pas|cmm|ptd|pro)$/i} glob 'C:\users\perry_m\desktop\epic_test\pascal_code\*.*';
#iterate through the files in input directory
foreach $file (@files) {
print "$file\n";
#read the file into a single string
open FILEHANDLE, $file or die $!;
my $string = do { local $/; <FILEHANDLE> };
#perfrom REGEX on this string
########################################################
#fix the include formats to conform to normal PASCAL
$count = 0;
while ($string =~ m/%INCLUDE/g)
{
#%include
$count++;
}
if ($count > 0)
{
print " $count %INCLUDE\n";
}
$count = 0;
while ($string =~ m/INCLUDE/g)
{
#%INCLUDE;
$count++;
}
if ($count > 0)
{
print " $count INCLUDE\n";
}
$count = 0;
while ($string =~ m/(%include\s+')[A-Za-z0-9]+:([A-Za-z0-9]+.[A-Za-z]+')/g)
{
#$1$2;
$count++;
}
if ($count > 0)
{
print " $count XXXX:include \n";
}
}
这将根据需要产生输出,下面是一个示例:
C:\users\perry_m\desktop\epic_test\pascal_code\BRTINIT.PAS
1 INCLUDE
2 XXXX:include
39 external and readonly
但是,如果我更改了正则表达式操作以尝试实现替换,则使用上面注释行中显示的替换操作,脚本将挂起并且永远不会返回。 我以为它与内存有关,但是我对Perl还是陌生的。 我还试图避免如果可能的话按行分析文件。
例:
while ($string =~ s/%INCLUDE/%include/g)
{
#%include
$count++;
}
和
while ($string =~ s/(%include\s+')[A-Za-z0-9]+:([A-Za-z0-9]+.[A-Za-z]+')/$1$2;/g)
{
#$1$2;
$count++;
}
编辑:简化示例
问题出在您的while
循环上。 像这样的循环
while ($string =~ m/INCLUDE/g) { ... }
将针对目标字符串中每次出现INCLUDE
都执行一次,但是类似
$string =~ s/INCLUDE/%INCLUDE;/
将一次性完成所有替换,并重新获取替换的数量。 如此循环
while ($string =~ s/INCLUDE/%INCLUDE;/g) { ... }
在每一个INCLUDE
之前和分号后面都会不断添加越来越多的百分号。
要查找更换的数量,请将所有循环更改为
$count = $string =~ s/INCLUDE/%INCLUDE;/g
s/INCLUDE/%INCLUDE/g
中的模式也将与替换匹配,因此,如果您在while循环中运行它,它将永远运行(直到内存不足)。
s///g
可以一次性替换所有比赛,因此您很少需要将其放在循环中。 m//g
也一样,如果将其放在列表上下文中,它将一步完成计数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.