Har*_*nry 2 regex perl templates
我正在尝试根据一些输入在 perl 中自动生成一个正则表达式模式,以处理通过在 Makefile 中粘贴令牌创建的各种变量......因此,例如,我可能有一个模式,例如:
foo_1_$(AB)_$(CB)
Run Code Online (Sandbox Code Playgroud)
鉴于这种模式,我需要创建一个正则表达式,将所有实例转换foo_1_\$(\w+)_\$(\w+)为bar_1_\$($1)_\$($2). 我遇到的主要问题是模式的“to”端——我$每次都需要增加数字引用——注意在任何给定模式中可能有可变数量的标记。
所以......我在想这样的事情:
foreach $pattern (@patterns) {
my $from = $pattern;
# foo_1_$(AB)_$(CD)
$from =~ s/\$\(\w+\)/\$\(\\w\\\+\)/g;
# foo_1_$(\w+)_$(\w+)
my $to = $pattern =~ s/foo/bar/r;
# bar_1_$(AB)_$(CD);
$to =~ s/\$\(\w+\)/\\\$\(\$?)/g; #???
# bar_1_\$($1)_\$($2)
# ^ ^
#this next part is done outside of this loop, but for the example code:
$line ~= s/\Q$from\E/$to/;
}
Run Code Online (Sandbox Code Playgroud)
如何使我的每个后续替换to具有增量索引?
编写代码以根据给定的模式生成正则表达式是一项复杂的工作(最简单的情况除外),这就是精确指定该模式可以是什么的时候。在这种情况下,我也不明白为什么不能通过为给定类型的模式编写正则表达式来解决问题(而不是编写会编写正则表达式的代码)。†
在任何一种情况下,都需要那些正则表达式,所以这里有一些。由于没有给出关于可能出现的模式的精确规则,我使用了从问题中的提示中得出的一些基本假设。
我认为要替换的模式 ( foo_) 后跟一个数字,然后是模式_$(AB)(文字美元和里面有字符的括号),重复任意次数(“可能有可变数量的标记”)。
解决此问题的一种方法是匹配整个以下模式(所有重复)。前瞻
s/[a-z]+_([0-9]+)(?=_(\$\(\w+\))+)/XXX_$1/;
Run Code Online (Sandbox Code Playgroud)
一个简单的单行测试
perl -wE'$_=q{foo_1_$(AB)_$(CB)}; s/[a-z]+_([0-9]+)(?=_(\$\(\w+\))+)/XXX_$1/; say'
Run Code Online (Sandbox Code Playgroud)
替换foo为XXX. 它仅适用于一组_$(AB),也适用于两个以上。
这不符合根据问题的“精神”决定的唯一的foo_1,没有遵循_$(AB)的(因为没有说明这样的要求)。如果这种情况实际上也应该匹配,那么可以通过一些小的更改(主要与移动_到要替换的模式有关,作为可选的 ( [a-z]+_[0-9]+_?))
更新 如果后面foo_(被替换)的“标记”实际上可以是任何东西(所以不一定$(..)),除了它们与 串在一起_,那么我们可以使用类似的修改
/[a-z]+_(\d?)(?=(_[^_]+)*)/XXX_$1/;
Run Code Online (Sandbox Code Playgroud)
foo_根据注释中给出的示例,后面的数字是可选的。但那就更简单了
/[a-z]+(?=(_[^_]+)*)/XXX/;
Run Code Online (Sandbox Code Playgroud)
例子
perl -wE'
$_=q{foo_$(AB)_123_$(CD)_foo_$(EF)}; say;
s/[a-z]+(?=(_[^_]+)*)/XXX/; say'
Run Code Online (Sandbox Code Playgroud)
印刷
foo_$(AB)_123_$(CD)_foo_$(EF) XXX_$(AB)_123_$(CD)_foo_$(EF)
注意:上述正则表达式的作用也是由/[a-z]+(?=_)/XXX/. 但是,上面更详细的正则表达式可以根据更精确的要求进行调整和调整,我会使用它或其变体作为完整解决方案的主要构建块。
如果可能是模式的规则结构化程度较低(少于“与_”相关的任何标记),那么我们需要知道它们,而且可能非常精确。
这显然不会按照要求从给定模式生成正则表达式,而是匹配此类(类)模式的正则表达式。如果有足够的规范说明这些模式可能是什么样的,这可以解决问题——这对于正则表达式生成也是必要的。
†另一种选择是使用了一些模板系统,但随后您再次直接编写正则表达式来匹配给定类型的模式。