合并含可变数量捕获组的两个正则表达式问题求助
正则匹配捕获组冗余问题
需求说明
尝试匹配以下两个正则表达式之一,将匹配的捕获组存入列表,但合并正则的尝试均产生多余的无用捕获:
第一个正则:
(\S+)(=)([fisuo])
第二个正则:
(\S+)(!)
注:此处的!仅为普通字符,并非逻辑非。
测试代码
#!/usr/bin/perl #-*- cperl -*- # $Id: test7,v 1.1 2023/04/10 02:57:12 bennett Exp bennett $ # use strict; use warnings; use Data::Dumper; foreach my $k ('debugFlags=s', 'verbose!') { my @v; # 以下是符合预期的匹配逻辑 if(@v = $k =~ m/^(\S+)(=)([fisuo])$/) { printf STDERR ("clownMatch = '$k' => %s\n\n", Dumper(\@v)); } elsif(@v = $k =~ m/^(\S+)(!)$/) { printf STDERR ("clownMatch = '$k' => %s\n\n", Dumper(\@v)); } @v = (); # 这是失败的合并尝试,会产生冗余捕获 if(@v = $k =~ m/^(?:(\S+)(=)([fisuo]))|(?:(\S+)(!))$/) { printf STDERR ("hopefulMatch = '$k' => %s\n\n", Dumper(\@v)); } printf STDERR "===\n"; } exit(0); __END__
输出结果
clownMatch = 'debugFlags=s' => $VAR1 = [ 'debugFlags', '=', 's' ]; hopefulMatch = 'debugFlags=s' => $VAR1 = [ 'debugFlags', '=', 's', undef, undef ]; === clownMatch = 'verbose!' => $VAR1 = [ 'verbose', '!' ]; hopefulMatch = 'verbose!' => $VAR1 = [ undef, undef, undef, 'verbose', '!' ]; ===
后续思考(更新于2023年4月10日 PDT 23:15:40)
结合建议,将问题拆解为三个小问题:
- 正则表达式能否返回可变数量的捕获组?目前尚无明确答案。
- 若可以,是否应这样使用正则表达式?除非有充分理由,否则不建议。
- 就我的需求而言,是否应使用正则表达式实现词法分析器/解析器的功能?不应如此。原本用正则做语法检查,结果偏离了方向。
此次尝试学到了很多,希望保留此帖作为警示案例。感谢@Schwern的最先回复。
内容的提问来源于stack exchange,提问作者Erik Bennett
相关产品推荐
相关产品推荐

