在行中匹配和替换多个$变量

时间:2012-08-27 22:57:36

标签: regex perl

我正在尝试为python转换器编写一个非常基本的shell,我在替换变量时遇到了一些麻烦。例如,我想:

echo $var1 $var2 $var3
echo $var1 $var2 $var3 $var4

成为:

print var1, var2, var3
print var1, var2, var3, var4

目前,它变为:

print var1, var2 var3
print var1, var2 var3, var4

我的正则表达式是:

$string =~ s/(\$[a-z]+[a-z0-9]*)(\s+\S+)/$1,$2/gi;

由于某种原因,即使设置了全局修饰符,它也不会再将正则表达式应用于匹配字符串的第二部分。

非常感谢任何帮助!

4 个答案:

答案 0 :(得分:1)

保持接近你的正则表达式,试试这个:

use strict;
use warnings;

my $string = '$var1 $var2 $var3 $var4$var5';

$string =~ s/\$([a-z][a-z0-9]*)\s*/$1, /gi;
$string =~ s/,\s*$//; #removing trailing comma
print $string . "\n";

<强>输出:

var1, var2, var3, $var4

或者我只是这样做,这可能会或可能不会与你可能有的其他事情一起使用。

s/\$(\w+)\s*/$1, /g

答案 1 :(得分:0)

您只需要将正则表达式修改为:

$string =~ s/\$([a-z][a-z0-9]*)(?:\s*|$)/$1, /gi; 
$string =~ s/,\s*$//; #courtesy Hameed

非捕获组将确保变量以空格结束,或者根本没有空格或者在行尾。

这也会匹配$var1 $var2 $var3 $var4$var6和输出var1, var2, var3, var4, var5, var6

等回声

答案 2 :(得分:0)

一旦匹配了(\ s + \ S +),正则表达式引擎移动了第二个变量。 超前断言将允许它在不消耗字符串

的情况下检查前方
 $string =~ s{
   \$ 
   ( [a-z]+[a-z0-9]* )  # capture varname
   (?=\s+\S+)           # lookahead
 } {$1,}gix ;

请注意,我既不匹配也不捕获\ s + S +,因此无需在替换字符串中将其包含为$ 2。而且/ x允许我将正则表达式空格化并添加添加注释。

注意 - 其他答案可能会与您要做的事情更加匹配。我只是解释你没有匹配第二个变量的具体查询。

答案 3 :(得分:0)

根据变量是否出现在

行的末尾,使您的替换成为条件
$string =~ s{\$([a-z]+[a-z0-9]*)(\s*$)?}{ defined $2 ? $1 : "$1," }ge;

$2对应的子模式为(\s*$)??使匹配成为可选项,因此仅当该模式成功匹配时才会定义$2,即,对于行上的最后一个变量 - 即使存在不可见的尾随空格。对于“内部”变量,请在末尾附加逗号。否则,变量名只会这样做。

例如

#! /usr/bin/env perl

use strict;
use warnings;

while (defined(my $string = <DATA>)) {
  $string =~ s{\$([a-z]+[a-z0-9]*)(\s*$)?}{ defined $2 ? $1 : "$1," }ge;
  $string =~ s/\becho\b/print/g;  # for demo only
  print $string, "\n";
}

__DATA__
echo $var1 $var2 $var3
echo $var1 $var2 $var3 $var4

输出:

print var1, var2, var3
print var1, var2, var3, var4