如何在Perl中的regexp中正确停止和启动元字符插值
请原谅,编辑要更简洁 我需要能够使用可能包含以下字符之一的字符串从数组grep:“.”、“+”、“/”、“-”。该字符串将通过从用户处捕获。数组包含我正在搜索的文件的每一行,我将文件放入数组中,以避免在用户与程序交互时将其打开,因为它位于cron上,我不希望在cron运行时将其打开,每行中都有一个唯一的标识符,它是regexp中使用的搜索字符串的基础。下面的代码显示了我正在使用的grep语句,我在程序中使用了OUR和MY,以使我希望在所有名称空间中访问的变量可用,而我仅在子例程中使用的变量不可用。如果您确实想尝试复制该问题如何在Perl中的regexp中正确停止和启动元字符插值,regex,perl,interpolation,metacharacters,Regex,Perl,Interpolation,Metacharacters,请原谅,编辑要更简洁 我需要能够使用可能包含以下字符之一的字符串从数组grep:“.”、“+”、“/”、“-”。该字符串将通过从用户处捕获。数组包含我正在搜索的文件的每一行,我将文件放入数组中,以避免在用户与程序交互时将其打开,因为它位于cron上,我不希望在cron运行时将其打开,每行中都有一个唯一的标识符,它是regexp中使用的搜索字符串的基础。下面的代码显示了我正在使用的grep语句,我在程序中使用了OUR和MY,以使我希望在所有名称空间中访问的变量可用,而我仅在子例程中使用的变量不可用
#!/usr/bin/perl -w
use strict;
use Switch;
use Data::Dumper;
our $pgm_path = "/tmp/";
our $device_info = "";
our @new_filetype1 = ();
our @new_filetype2 = ();
our @dev_info = ();
our @pgm_files = ();
our %arch_rtgs = ();
our $file = "/path/file.csv";
open my $fh, '<', $file or die "Couldn't open $file!\n";
chomp(our @source_file = <$fh>);
close $fh;
print "Please enter the device name:\n";
chomp(our $dev = <STDIN>);
while ($device_info eq "") {
# Grep the device info from the sms file
my @sms_device = grep(/\Q$dev\E/, @source_file);
if (scalar(@sms_device) > 1) {
my $which_dup = find_the_duplicate(\@sms_device);
if ($which_dup eq "program") {
print "\n-> $sms_dev <- must be a program name instead of a device name." .
"\nChoose the device from the list you are working on, specifically.\n";
foreach my $fix(@sms_device) {
my @fix_array = split(',', $fix);
print "$fix_array[1]\n";
undef @fix_array;
}
chomp($sms_dev = <STDIN>);
} else { $device_info = $which_dup; }
} elsif (scalar(@sms_device) == 1) {
($device_info) = @sms_device;
@sms_device = ();
}
}
没有注意到来自该程序的更多活动。它只是坐在那里,好像在等待用户的更多输入。这不是我所期望的。我之所以要锚定搜索模式,是因为有很多类似命名设备的示例,它们与搜索模式具有相同的字符顺序,但也包括在regexp计算中忽略的其他字符。我不希望它们被忽略,因为它们包含在匹配中。我想强制变量中字符串的精确匹配
提前感谢您仔细阅读了我毫无经验的代码,并试图通过交流详细说明我的问题。我会使用quotemeta。下面是一个比较示例:
my $regexp = '\t';
my $metaxp = quotemeta ($regexp);
while (<DATA>) {
print "match \$regexp - $_" if /$regexp/;
print "match \$metaxp - $_" if /$metaxp/;
}
__DATA__
This \t is not a tab
This is a tab
希望你明白我的意思
我认为添加$regexp=quotemeta$regexp或在捕获标准输入时执行此操作应该满足您的需要。设备id后跟字符串的开头/\Q$dev\E^/毫无意义。您希望设备id前面是字符串的开头,后面是字符串的结尾
grep { /^\Q$dev\E\z/ }
更好的是,让我们避免无缘无故地启动正则表达式引擎
grep { $_ eq $dev }
比如说,
$ perl -e'my $dev = "ccc"; CORE::say for grep { /^\Q$dev\E\z/ } qw( accc ccc ccce );'
ccc
$ perl -e'my $dev = "ccc"; CORE::say for grep { $_ eq $dev } qw( accc ccc ccce );'
ccc
你为什么用我们的???除非有需要,否则您不应使用我们的,例如@ISA和@EXPORT。您的要求不清楚。$regexp是否包含一个regex模式,或文本以逐字匹配?你有什么问题?你没能证明你的问题。明白你说它不起作用是什么意思吗?Regexp元字符类似于$work after\E。但可能您的正则表达式不是您所想的,或者$Regexp末尾有空格,因此您的输入将与正则表达式不匹配。很难说没有看到具体数据。请回答您的问题并添加硬编码数据以重现问题。但基本上不是同一件事:请澄清您的意思。@ikegami我使用我们的和我的,因为上面有骆驼和骆驼的Perl书籍告诉我这样做。regexp可能包含也可能不包含任何元字符,并且需要进行文字匹配,但是当我尝试锚定regexp以不匹配任何其他字符时,就会出现问题,例如:ABC=~/ABC/;这很好。ABCD=~/ABC^/;这很好。ABCD=~/ABC/;我不想和这个相配。这就是问题所在。当我尝试锚定时,程序在评估期间冻结。是的,先生。那是个打字错误。代码应该有一个“$”而不是“^”。我的错,不,不应该。应该是\z。正如你所看到的,它是有效的。如果您仍有其他想法,请随时提供您的问题的演示。看,我真的很感谢你试图帮助我,但是我不能让你的方法在perl脚本中工作,也不能从命令行工作[kthmgr@q4098bin]$perl-e'open$fh,Re-CORE::say不是关键字,您使用的是旧版本的perl。使用print$\n而不是CORE::sayOk,使用这两种方法,我都无法从程序中获得匹配项:请输入程序名:match+此No matches foundAah,有趣的。。。诚然,我不知道关于\Q\E的情况。唉,如果他使用\Q,那不是每次都会查找字符串$dev吗?显然不是,根据您的回答…\Q仍然允许插值和其他字符串文字操作,例如。\L。它甚至允许\在双引号字符串文字中正常工作
grep { $_ eq $dev }
$ perl -e'my $dev = "ccc"; CORE::say for grep { /^\Q$dev\E\z/ } qw( accc ccc ccce );'
ccc
$ perl -e'my $dev = "ccc"; CORE::say for grep { $_ eq $dev } qw( accc ccc ccce );'
ccc