我的文本输入与以下所示类似。我想在每个'a = b'模式前添加单词auto
,但前提是它是关键字kywrd
之后的序列的一部分(由分号分隔)。
kywrd a=b;c=d;
e=f;
fnctn z;
g=h;
所以我在这里寻找的输出是:
kywrd2 auto a=b;auto c=d;
auto e=f;
fnctn z;
g=h;
以下Perl6(Raku?)代码使用正则表达式添加auto
关键字,但仅在 first a=b
模式之前。有没有一种简单的方法可以执行序列中所有模式的替换;保留g=h;
不变?
my Str $x = slurp "in.q";
$x ~~ s:g /kywrd\s+(\w+)\=(\w+)\;/kywrd2 auto $0=$1\;/;
spurt "out.q", $x;
答案 0 :(得分:5)
一种使正则表达式最小化的可能方法:
sub repl ($input)
{
$input.Str
.split(';', :skip-empty)
.map( 'auto ' ~ * ~ ';')
.join('')
};
my $foo = 'kywrd a=b;c=d;d=e;';
$foo ~~ s:g /kywrd \s+ (.+)/kywrds2 { repl($0) }/;
$foo.say;
相对于subst
运算符,我个人更喜欢使用s//
形式的方法。
$foo .= subst(/ kywrd \s+ (.+) /, "kywrds2 { repl($0) }", :g);
答案 1 :(得分:5)
一种方法:
const common = require("./common");
module.exports = {
test: function(){
console.log(common.data);
}
}
对于稍微熟悉Raku的人来说,我展示的所有代码都将很容易理解,但是我还是会解释它。
我已经分解出一个命名的正则表达式来匹配一对。 (有关# Create a separate named regex that captures an `x=y;` pair:
my regex pair { (\w+) \= (\w+) \; (\s*) }
# (Capture `(\s*)` so formatting between pairs is retained)
# Generate and return 'auto'-ized replacement of a captured pair:
sub auto-ize ($/) { "auto $0=$1;$2" }
$x ~~ s:g { kywrd \s+ <pair>+ } = "kywrd2 $<pair>».&auto-ize.join()";
为何/如何调用<pair>
正则表达式的详细信息,请参见my answer to Difference in capturing and non-capturing regex scope in Perl 6 / Raku。)
pair
子例程使用the match variable(auto-ize
)作为参数。这很方便,因为$/
等会自动别名为与传递的匹配对象关联的编号捕获。
我使用了$0
形式的语法,因为我认为这种用例更易读。 (请参见s///
doc中提到的“不同定界符”。)
“ kywrd2 ...”字符串将被反复求值并替换为一个匹配项,对于多个s [ ... ] = " ... "
匹配项中的每个匹配项都为一次。
s:g
位是双引号字符串规则下的代码interpolated。
$<pair>».&auto-ize.join()
表示$<pair>
的缩写,即$/<pair>
的{{1}}键。它是指与the match variable关联的<pair>
命名捕获。后者将依次对应于多个$/
匹配中的每个匹配。
正则表达式pair
中的s:g
量词表示,如果匹配,它将生成捕获(匹配)对象的 +
而不是仅仅一个(如果表达式只是<pair>+
或List
就是这种情况)。
»
将其LHS操作数视为树或列表(在这种情况下,是一个<pair>
对中一个或多个捕获/匹配对象的列表),并遍历其元素。对于每个“叶”元素,<pair>?
在其右侧进行操作。 (foo=bar;...
是一个功能强大的运算符,但具有很好的简单用例,例如在这种情况下,它在符号上非常方便且紧凑,等效于»
循环。如果您将其写为»
,首选ASCII。)
for
调用>>
子例程,就好像它是一个方法一样,使用其左侧的操作数作为第一个参数。
来自@PolarBear答案的测试输入数据:
.&auto-ize
将其放入auto-ize
中,然后kywrd a=b;c=d;
e=f;
fnctn z;
g=h;
k=m;
fnctn y;
kywrd m=n;
k=j;
kywrd z=a;b=i;
kywrd c=x;e=i;
z=q;
fnctn o;
将生成的in.q
显示为:
say
答案 2 :(得分:3)
不是很优雅,但是可行的代码(古老的方式)
#!/usr/bin/perl
use strict;
use warnings;
OUTER: while(<DATA>) {
if( s/kywrd /kywrd2 / ) {
do {
if( ! s/(\w+)=(\w+)/auto $1=$2/g ) {
print;
next OUTER;
}
print;
} while ( <DATA> );
} else {
print;
}
}
__DATA__
kywrd a=b;c=d;
e=f;
fnctn z;
g=h;
k=m;
fnctn y;
kywrd m=n;
k=j;
kywrd z=a;b=i;
kywrd c=x;e=i;
z=q;
fnctn o;
我需要看看Raku-它是哪种动物。