Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在行中匹配和替换多个$variables_Regex_Perl - Fatal编程技术网

Regex 在行中匹配和替换多个$variables

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/(\$

我正在尝试编写一个非常基本的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/(\$[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+
在这种情况下是不对的?