Regex 在行中匹配和替换多个$variables
我正在尝试编写一个非常基本的shell-to-python转换器,但在替换变量时遇到了一些问题。例如,我想:Regex 在行中匹配和替换多个$variables,regex,perl,Regex,Perl,我正在尝试编写一个非常基本的shell-to-python转换器,但在替换变量时遇到了一些问题。例如,我想: 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/(\$
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;
出于某种原因,即使设置了全局修饰符,它也不会将正则表达式再次应用于匹配字符串的第二部分
非常感谢您的帮助 靠近您的正则表达式,尝试以下操作:
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
请靠近您的正则表达式,尝试以下操作:
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
您只需将正则表达式修改为:
$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
您只需将正则表达式修改为:
$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
匹配(\s+\s+)后,正则表达式引擎已通过第二个变量。
lookahead断言将允许它在不使用字符串的情况下检查前面的内容
$string =~ s{
\$
( [a-z]+[a-z0-9]* ) # capture varname
(?=\s+\S+) # lookahead
} {$1,}gix ;
请注意,我既不匹配也不捕获\s+s+,因此无需将其作为$2包含在替换字符串中。并且/x允许我将正则表达式隔开并添加注释
注意——其他答案可能与你想做的事情更接近。我只是解释您关于不匹配第二个变量的具体查询 匹配(\s+\s+)后,正则表达式引擎将移动并通过第二个变量。 lookahead断言将允许它在不使用字符串的情况下检查前面的内容
$string =~ s{
\$
( [a-z]+[a-z0-9]* ) # capture varname
(?=\s+\S+) # lookahead
} {$1,}gix ;
请注意,我既不匹配也不捕获\s+s+,因此无需将其作为$2包含在替换字符串中。并且/x允许我将正则表达式隔开并添加注释
注意——其他答案可能与你想做的事情更接近。我只是解释您关于不匹配第二个变量的具体查询 根据变量是否出现在带
$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
#/usr/bin/env perl
严格使用;
使用警告;
while(已定义(my$string=)){
$string=~s{\$([a-z]+[a-z0-9]*)(\s*$)?}{定义的$2?$1:“$1,”}ge;
$string=~s/\becho\b/print/g;#仅用于演示
打印$string,“\n”;
}
__资料__
echo$var1$var2$var3
echo$var1$var2$var3$var4
输出:
print var1, var2, var3
print var1, var2, var3, var4
打印var1,var2,var3
打印var1、var2、var3、var4根据变量是否出现在具有
$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
#/usr/bin/env perl
严格使用;
使用警告;
while(已定义(my$string=)){
$string=~s{\$([a-z]+[a-z0-9]*)(\s*$)?}{定义的$2?$1:“$1,”}ge;
$string=~s/\becho\b/print/g;#仅用于演示
打印$string,“\n”;
}
__资料__
echo$var1$var2$var3
echo$var1$var2$var3$var4
输出:
print var1, var2, var3
print var1, var2, var3, var4
打印var1,var2,var3
打印var1,var2,var3,var4好的一个。尽管此字符串将失败:
echo$var1$var2$var3$var4$var6
。另外,您不需要A-Z
,因为您已经在末尾使用了不敏感标志。@kash您是对的。我现在修好了。但是,它将添加一个尾随的,
,下面的解决方案也是如此。不知道如何避免添加尾随逗号。很好。是否有一个在线测试仪,我们可以在那里测试perl代码(不仅仅是正则表达式,还包括替换代码)?我认为我们可以捕获不同组中的最后一个变量,然后尝试$1,$2
。不确定这是否有效。@Kash它就在我们之前的行动中。。。哈哈,我觉得自己真的很蠢。嗯,那不是只有var1和var3才匹配吗?我认为\S+
在这种情况下不正确?很好。尽管此字符串将失败:echo$var1$var2$var3$var4$var6
。另外,您不需要A-Z
,因为您已经在末尾使用了不敏感标志。@kash您是对的。我现在修好了。但是,它将添加一个尾随的,
,下面的解决方案也是如此。不知道如何避免添加尾随逗号。很好。是否有一个在线测试仪,我们可以在那里测试perl代码(不仅仅是正则表达式,还包括替换代码)?我认为我们可以捕获不同组中的最后一个变量,然后尝试$1,$2
。不确定这是否有效。@Kash它就在我们之前的行动中。。。哈哈,我觉得自己真的很蠢。嗯,那不是只有var1和var3才匹配吗?我认为\S+
在这种情况下是不对的?