regex - 如何将替换正则表达式作为命令行参数传递给 perl 脚本

标签 regex perl

我正在尝试编写一个简单的 perl 脚本,以将给定的正则表达式应用于文件名等,但我在将正则表达式作为参数传递到脚本中时遇到问题。

我希望能够做的是这样的事情:

> myscript 's/hi/bye/i' hi.h
bye.h
>

我已经生成了这段代码

#!/utils/bin/perl -w
use strict;
use warnings;

my $n_args = $#ARGV + 1;
my $regex =  $ARGV[0];
for(my $i=1; $i<$n_args; $i++) {
  my $file = $ARGV[$i];

  $file =~ $regex;
  print "OUTPUT: $file\n";
}

我无法使用 qr,因为显然它不能用于替换正则表达式(尽管我的来源是论坛帖子,所以我很高兴被证明是错误的)。

我宁愿避免将两个部分作为单独的字符串传递并在 perl 脚本中手动执行正则表达式。

是否可以将正则表达式作为这样的参数传递,如果可以,最好的方法是什么?

最佳答案

我认为,有不止一种方法可以做到这一点。

永恒之道:

当您基本上发送正则表达式时,可以对其进行求值以获得结果。像这样:

my @args = ('s/hi/bye/', 'hi.h');
my ($regex, @filenames) = @args;
for my $file (@filenames) {
  eval("\$file =~ $regex");
  print "OUTPUT: $file\n";
}

当然,遵循这种方式会给你带来一些非常令人讨厌的惊喜。例如,考虑传递这组参数:

...
my @args = ('s/hi/bye/; print qq{MINE IS AN EVIL LAUGH!\n}', 'hi.h');
...

是的,它会非常邪恶地 mock 你。

安全方法:

my ($regex_expr, @filenames) = @args;
my ($substr, $replace) = $regex_expr =~ m#^s/((?:[^/]|\\/)+)/((?:[^/]|\\/)+)/#;
for my $file (@filenames) {
  $file =~ s/$substr/$replace/;
  print "OUTPUT: $file\n";
}

如您所见,我们将给定的表达式解析为两部分,然后使用这些部分构建一个完整的运算符。显然,这种方法不太灵活,但当然它更安全。

最简单的方法:

my ($search, $replace, @filenames) = @args;
for my $file (@filenames) {
  $file =~ s/$search/$replace/;
  print "OUTPUT: $file\n";
}

是的,没错 - 根本没有正则表达式解析!这里发生的事情是我们决定采用两个参数——“搜索模式”和“替换字符串”——而不是单个参数。它会让我们的脚本不如前一个脚本灵活吗?不,因为我们仍然必须或多或少定期解析正则表达式。但现在用户可以清楚地了解提供给命令的所有数据,这通常是一个很大的进步。 )

两个示例中的@args都对应于@ARGV数组。

关于regex - 如何将替换正则表达式作为命令行参数传递给 perl 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12423337/

相关文章:

mysql - SQL中的正则表达式检测一个或多个数字

regex - sed 不会匹配下一行

regex - 如何通过 perl 和 regex 验证一个字符串只包含某些字母

multithreading - 线程中的 Perl getstore

python - 提取两个子字符串之间匹配的字符串部分

perl - 打印文件的每一行

perl 将数字替换为字母,与 for 一起使用

c++ - 将字符串作为正则表达式模式输入传递。 (非标量误差)

sql - Where 子句中的数字通配符

正则表达式和下一个符号不是 '('