我正在尝试匹配其中之一
(\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;
# Below is the offensive looking code. I was hoping for a regex
# which would behave like this:
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 = ();
# This is one of my failed, aspirational matches. I think I know
# WHY it fails, but I don't know how to fix it.
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日23:15:40 PDT
在几位读者的智慧输入下,似乎这个问题可以分解成几个较小的问题。
正则表达式能否返回可变数量的捕获组?
我还没有听说过。
如果可以,是否应该使用正则表达式来实现这种方式?
没有充分的理由就不应该使用。
对于我的目的,我应该使用正则表达式来创建真正的词法分析器/解析器吗?
不应该。我之前使用正则表达式进行语法检查时有些过头了。
虽然如此,我学到了很多东西。我希望管理员能够将这篇文章作为一则警示故事。
每个人都应该得到积分,并声称他们被剥夺了,引用本段文字即可。@Schwern因为第一个回答而获得了积分。谢谢。
@v
可以是长度为2或3,具体取决于哪个子正则表达式匹配,就像输出中的 clownMatch 示例一样。 - Erik Bennett^(\S+)(?|(=)([fisuo])|(!)())$
。 - bobble bubble