如何在Perl中的regexp中正确停止和启动元字符插值

如何在Perl中的regexp中正确停止和启动元字符插值,regex,perl,interpolation,metacharacters,Regex,Perl,Interpolation,Metacharacters,请原谅,编辑要更简洁 我需要能够使用可能包含以下字符之一的字符串从数组grep:“.”、“+”、“/”、“-”。该字符串将通过从用户处捕获。数组包含我正在搜索的文件的每一行,我将文件放入数组中,以避免在用户与程序交互时将其打开,因为它位于cron上,我不希望在cron运行时将其打开,每行中都有一个唯一的标识符,它是regexp中使用的搜索字符串的基础。下面的代码显示了我正在使用的grep语句,我在程序中使用了OUR和MY,以使我希望在所有名称空间中访问的变量可用,而我仅在子例程中使用的变量不可用

请原谅,编辑要更简洁

我需要能够使用可能包含以下字符之一的字符串从数组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