Regex 如何在Perl中进行条件贪婪匹配?
我希望Perl解析代码文本并识别某些内容,例如代码:Regex 如何在Perl中进行条件贪婪匹配?,regex,perl,conditional,match,greedy,Regex,Perl,Conditional,Match,Greedy,我希望Perl解析代码文本并识别某些内容,例如代码: use strict; use warnings; $/ = undef; while (<DATA>) { s/(\w+)(\s*<=.*?;)/$1_yes$2/gs; print; } __DATA__ always @(posedge clk or negedge rst_n) if(!rst_n)begin d1 <= 0; //perl_comment_4 //
use strict;
use warnings;
$/ = undef;
while (<DATA>) {
s/(\w+)(\s*<=.*?;)/$1_yes$2/gs;
print;
}
__DATA__
always @(posedge clk or negedge rst_n)
if(!rst_n)begin
d1 <= 0; //perl_comment_4
//perl_comment_5
d2 <= 1 //perl_comment_6
+ 2;
end
else if( d3 <= d4 && ( d5 <= 3 ) ) begin
d6 <= d7 +
(d8 <= d9 ? 1 : 0);
//perl_comment_7
d10 <= d11 <=
d12
+ d13
<= d14 ? 1 : 0;
end
使用严格;
使用警告;
$/=未定义;
而(){
s/(\w+)(\s*这比您想象的要复杂得多,如果不为您试图处理的语言编写解析器,就不可能正确地完成。但是,如果您的示例始终是该语言的有限子集,您可能会很幸运
我能看到的最好的方法是使用split
从要进行替换的“顶层”部分中分离出括号中的字符串的所有子部分。然后可以对相关部分进行更改,并将拆分部分重新连接在一起
甚至这也依赖于代码有适当平衡的圆括号,并且出现在字符串或注释中的奇怪的开括号或闭括号将抛出该过程。split
中使用的正则表达式必须是递归的,以便可以匹配嵌套的圆括号,将其设为捕获正则表达式将返回split
字符串的所有部分,而不仅仅是匹配之间的部分
此代码将按照您的要求执行,但请注意,正如我所描述的,它非常脆弱
use strict;
use warnings;
my $data = do {
local $/;
<DATA>;
};
my @split = split / ( \( (?> [^()] | (?1) )* \) ) /x, $data;
for ( @split ) {
next if /[()]/;
s/ ^ \s* \w+ \K (?= \s* <= ) /_yes/xgm;
}
print join '', @split;
__DATA__
always @(posedge clk or negedge rst_n)
if(!rst_n)begin
d1 <= 0; //perl_comment_4
//perl_comment_5
d2 <= 1 //perl_comment_6
+ 2;
end
else if( d3 <= d4 && ( d5 <= 3 ) ) begin
d6 <= d7 +
(d8 <= d9 ? 1 : 0);
//perl_comment_7
d10 <= d11 <=
d12
+ d13
<= d14 ? 1 : 0;
end
使用严格;
使用警告;
我的$data=do{
本地$/;
;
};
我的@split=split/(\((?>[^()]|(?1))*\)/x,$data;
对于(@split){
下一个if/[()]/;
s/^\s*\w+\K(?=\s*检查并编写该语言的语法分析器。请参见或.Katyusza,您可以删除if\s*
,它将是一个语法分析器。解析Verilog并不是一件小事:@Katyusza:如果您这样做,那么您应该意识到您正在为自己设置一个巨大的任务。但是请注意您可能使用的模块。您注定要失败如果你从简单开始regexes@katyusza它类似于s/(\((?>[^()]+|(?1))*\)(*跳过)(*F)|^\s*\w+\K(?=\s*@BobbleBobble:我已经做了我认为你的意思是的更改,但是这些更改很小,而且我确信它们不会对程序的性能产生影响。除非数据量很大,否则这将是磁盘绑定的。我真的不知道该怎么做,而不是在一行的开头锚定:整个事情真的需要锚定在后面语句边界,可以是begin
的分号,也可以是其他的,如果它们在引号或注释中,则必须忽略它们。这真的不是一次性的工作regex@Borodin我不明白为什么要使用(*SKIP)(*F)
进行拆分/合并,这对于此类情况来说很方便,而且不“神奇”。它会丢弃您用作拆分序列的部分。如果锚定到行首或使用分号取决于输入。我更喜欢分号变体,但您的也可以。为了提高性能,我会在[^()]中添加+
量词
的交替性较低:vs或介于两者之间。详细的回答。@bobblebubble:正如我所说,没有正则表达式递归,这个问题是无法解决的。我判断\K
似乎在一个普通Perl程序员的词汇表中,而很少有人考虑回溯或了解star命令。如果你认为我的cr它是错误的,那么你复制它肯定也是错误的吗?