Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl Regex to Convert {a, b, c, ..., x} into (a|b|c|...|x)

I am learning Perl and practicing regexes and I want to have the following functionality:

Input

Wildcard style shell syntax

Output

Perl regex

I am well aware of Regexp::Wildcards but I want something smaller and I also want to write it myself for the educational benefit.

I am really stuck trying to write the regex for this. I have tried to list my requirements to help make the regex pattern reveal itself:

  • Start matching at a {
  • Keep a backreference to each comma-separated element, get rid of padded spaces
  • End matching at a }

However, this just introduced more questions in my mind

  • How do I keep backreferences to an arbitrarily long list?

Example

Suppose the input is {foo, bar}.c. The substitute operator should transform this to (foo|bar).c.

like image 968
Think Avatar asked Sep 30 '22 05:09

Think


1 Answers

You don't keep a dynamic list of back references.

Instead, you break up this problem into steps:

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

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

Outputs:

(a|b|c|d|...|x)

It's also possible to do this using a double layer search and replace, like so:

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

print $string;
like image 101
Miller Avatar answered Oct 08 '22 10:10

Miller