1

我正在尝试编写一个非常基本的 shell 到 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;

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

非常感谢您的帮助!

4

4 回答 4

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
于 2012-08-27T23:17:41.493 回答
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

输出:

打印 var1、var2、var3
打印 var1、var2、var3、var4
于 2012-12-06T13:38:51.457 回答
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

于 2012-08-27T23:43:24.657 回答
0

一旦它与 (\s+\S+) 匹配,正则表达式引擎已移动通过第二个变量。前瞻断言将允许它在不消耗字符串的情况下检查前面的内容

 $string =~ s{
   \$ 
   ( [a-z]+[a-z0-9]* )  # capture varname
   (?=\s+\S+)           # lookahead
 } {$1,}gix ;

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

注意 - 其他答案可能会更接近您想要做的事情。我只是在解释您关于不匹配第二个变量的具体查询。

于 2012-08-28T06:48:50.297 回答