【问题标题】:Perl Regex to Convert {a, b, c, ..., x} into (a|b|c|...|x)Perl 正则表达式将 {a, b, c, ..., x} 转换为 (a|b|c|...|x)
【发布时间】:2014-09-20 06:46:14
【问题描述】:

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

输入

通配符样式的shell语法

输出

Perl 正则表达式

我非常了解 Regexp::Wildcards,但我想要更小的东西,而且我也想自己编写它以供教育。

我真的很难为此编写正则表达式。我试图列出我的要求以帮助使正则表达式模式显露出来:

  • 从 {
  • 开始匹配
  • 保留对每个逗号分隔元素的反向引用,去掉填充空格
  • 在 } 处结束匹配

然而,这只是在我的脑海中引入了更多的问题

  • 如何保持对任意长列表的反向引用?

示例

假设输入是{foo, bar}.c。替代运算符应将其转换为(foo|bar).c

【问题讨论】:

    标签: regex perl wildcard


    【解决方案1】:

    您不会保留反向引用的动态列表。

    相反,您将这个问题分解为几个步骤:

    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 修饰符。
    • 加入-拆分?这很有趣(而且有效),+1。下次也许你可以向我们展示一个 Split-Join-Split。 :)
    猜你喜欢
    • 2012-09-20
    • 1970-01-01
    • 2015-06-12
    • 2011-05-30
    • 2020-07-15
    • 2021-01-10
    • 1970-01-01
    • 2014-03-23
    • 1970-01-01
    相关资源
    最近更新 更多