我正在尝试为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;
由于某种原因,即使设置了全局修饰符,它也不会再将正则表达式应用于匹配字符串的第二部分。
非常感谢任何帮助!
答案 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