Regex 将{a,b,c,…,x}转换为(a | b | c | x)的Perl正则表达式

Regex 将{a,b,c,…,x}转换为(a | b | c | x)的Perl正则表达式,regex,perl,wildcard,Regex,Perl,Wildcard,我正在学习Perl并练习正则表达式,我希望具有以下功能: 输入 通配符样式的shell语法 输出 Perl正则表达式 我非常了解Regexp::通配符,但是我想要一些更小的,而且为了教育的利益,我也想自己编写它 我真的被困在为这个编写正则表达式的过程中了。我试着列出我的要求,以帮助regex模式显露出来: 从一开始就匹配{ 保留对每个逗号分隔元素的反向引用,去掉填充空格 在}处结束匹配 然而,这只是在我脑海中引入了更多的问题 如何保留对任意长列表的反向引用 例子 假设输入是{foo,ba

我正在学习Perl并练习正则表达式,我希望具有以下功能:

输入 通配符样式的shell语法

输出 Perl正则表达式

我非常了解Regexp::通配符,但是我想要一些更小的,而且为了教育的利益,我也想自己编写它

我真的被困在为这个编写正则表达式的过程中了。我试着列出我的要求,以帮助regex模式显露出来:

  • 从一开始就匹配{
  • 保留对每个逗号分隔元素的反向引用,去掉填充空格
  • 在}处结束匹配
然而,这只是在我脑海中引入了更多的问题

  • 如何保留对任意长列表的反向引用
例子
假设输入是
{foo,bar}.c
。替换运算符应将其转换为
(foo | bar).c

您没有保留反向引用的动态列表

相反,您可以将此问题分解为以下步骤:

my $string = "{a, b, c, d, ..., x}";

if ($string =~ m/\{(.*?)\}/) {
    my $str = join '|', split /,\s*/, $1;
    print "($str)";
}
产出:

(a|b|c|d|...|x)
也可以使用双层搜索和替换来完成此操作,如下所示:

$string =~ s{\{(.*?)\}}{
    my $list = $1;
    $list =~ s/,\s*/|/g;
    "($list)"
}eg;

print $string;

令人惊叹的。从来没有想过分层正则表达式,但我想这是有意义的,因为替换表达式可以是任何东西。当我有15个代表时,我将对此进行投票;)如果您使用s{([^}]*?)\}而不是s{(.*?)\},那么您可以将多个列表放在同一个字符串中。非贪婪匹配已经可以实现这一点。唯一值得关注的边缘情况是列表是否可以跨新行,在这种情况下需要/a修改器。Join-Split?这很有趣(也很有效),+1。下次也许你可以给我们看一个拆分连接拆分。:)