命令行参数推导作为特殊变量

时间:2017-02-09 23:42:59

标签: regex perl

Perl

中的简单脚本
#!/usr/bin/perl                                            
use v5.20.1;                                               
use strict;                                                
use warnings;                                              

$| = 1;                                                    

my $string     = $ARGV[ 0 ];                               
my $match      = $ARGV[ 1 ];                               
my $substitute = $ARGV[ 2 ];                               

$string =~ m/match/g; # just for capturing the pattern                                     

$string =~ s/$match/only $substitute/g;                    

say "\$1[itself]  == $1";                                  
say "\$substitute == $substitute";                         
say "\$string     == $string";                             
say "prefix      == $`";                                   
say "match       == $&";                                   
say "suffix      == $'"; 

输入和输出:

$ perl temp 'I have 9 dollars' '(\d+)' '$1'
$1[itself]  == 9
$substitute == $1
$string     == I have only $1 dollars
prefix      == I have 
match       == 9
suffix      == dollars  

我想要做的是通过从 @ARGV <初始化匹配替换变量来进行简单的替换 / strong>即可。之后,初始化 $ 1 等特殊字符的简单匹配。但是当我想将$1中的特殊字符command-line传递给脚本时,它会被扣除为常规字符串,而不是特殊变量 $ 1 我需要替换

如果我更改代码:

$string =~ s/$match/only $substitute/g;

到:

$string =~ s/$match/only $1/g;  

现在它有效!
1。为什么命令行的$1与脚本中的$1不同?
2。有什么办法可以解决吗?

我的控制台的屏幕截图:

enter image description here

修改

由于ikegami建议我安装并使用了String::Substitution,并且可以使用gsub_copy($line, $match, $substitute);推断出替换。 但是我仍然需要使用这个替换本身在屏幕上打印它并将其着色以说明发生了什么。
实际上,此目的是重命名脚本的一部分,该脚本读取所有文件并通过调用rename函数,更改文件的名称。

正如您在屏幕截图中看到的那样:

enter image description here

而不是for_$1屏幕上应该是for_Level。那么这个模块可以返回它推断的内容吗?
我不是在讨论匹配组括号子匹配! 该模块的作者也说:

  

此模块不保存或插入$&amp;避免相当大的   性能损失&#34;

这个截图可以澄清这个主题:

enter image description here

2 个答案:

答案 0 :(得分:2)

  

为什么$ 1的命令行与脚本中的$ 1不同?

你实际上在问为什么

"-Yuna99s993m": {
  "created": 1484634400,
  "status": "1"
  "entry": "1"
  "status_entry": "1_1"
"-Y8hj98nmswm": {
  "created": 1481623400,
  "status": "1"
  "entry": "3"
  "status_entry": "1_3"
脚本中的

不同
s/.../...$substitute.../
在你的脚本中

。出于同样的原因

s/.../...$1.../

不同
print($substitute);

这就是print($1); (捕获的文本)的值与$1$substitute)的值不同。

这就是你需要的:

$1

假设您在替换表达式之外实际上并不需要use String::Substitution qw( gsub_modify ); gsub_modify($string, $match, $substitue); ,并且您根本不需要$1和朋友。如果确实需要它们,那么您可以使用以下内容:

$&

答案 1 :(得分:-1)

强制性劝阻:不要这样做。基本上这只是在用户提供的字符串上运行eval,这真是个坏主意。

实际答案:使用ee修饰符(请参阅perlop)至s///eval表达式右侧部分的字符串:

$string =~ s/$match/"\"only $substitute\""/gee

顺便说一下,您不需要单独捕获模式,只需将$match放入s///表达式中的捕获组中:

$string =~ s/($match)/"\"only $substitute\""/gee