bradcathey has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monasterians:

Sorry for the convoluted title, but as penitence for using an "&" and no "()" in calling subroutines in my early scripts, I'm hoping to edit my code with a regular expression.

my $call = "&somesub"; $call =~ s/(&)(\w+(\([\"\w]*\))?)/$2/;

OR

my $call = "&somesub("foobar")"; $call =~ s/(&)(\w+(\([\"\w]*\))?)/$2/;

I want to end up with somesub() or somesub("foobar") respectively.

Question: How can I alter my regex to add the "()"s if they are not there, and leave them if they are? Thanks!


—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: Regex to add text if text is missing
by crashtest (Curate) on Jun 25, 2005 at 19:23 UTC
    Instead of constructing a more complicated regex, I'd just add an extra step by inserting empty parens after every bare ampersanded subroutine call:
    use strict; use warnings; local $/ = ";\n"; # Assumes each statement is followed by a newline! while (<DATA>){ s/((?> & \w+ \s*)) # Match ampersand, followed by subname # and optional whitespace. Use atomic # grouping ("?>") so perl won't backtrack # after this matches. ([^(]|$) # Ensure this is followed by a non-open-paren, # or this was the end of the statement. /$1()$2/gx; # If this matched, place () after the sub call. # OP's original substitution to remove "&" s/(&)(\w+(\([\"\w]*\))?)/$2/g; print "$_"; } __DATA__ &somesub; &somesub("foobar") my $foo = &bar(1); my @results = (&foo, &bar, &baz(1, "data")); my $stuff = (&foo, &baz(qw(other information), &data); &print;
    Note this will fail if your code ever passed arguments to a sub without using parentheses, like &print "a", "list", "of", "stuff". I'm sure there are other possible scenarios where this might fail, but maybe this can be a starting point.

Re: Regex to add text if text is missing
by halley (Prior) on Jun 25, 2005 at 19:03 UTC
Re: Regex to add text if text is missing
by TedPride (Priest) on Jun 25, 2005 at 20:37 UTC
    I imagine there's a more efficient way to do this with backwards or forwards looking, but I'm not that good at regex. The following works, even if it does more substitutions than are necessary:
    $_ = join '', <DATA>; # Add & to front of function calls without. s/&?(\w+\(.*?\))/&$1/g; # Add () to end of function calls without. s/(&\w+)(?:\((.*?)\))?/$1($2)/g; print; __DATA__ &somesub('args'); somesub('args'); &somesub;
    This way of doing things may have problems, however. You will end up not only replacing sub calls, but built-in function calls as well. You need to add a sub to check function names against a Perl function list, and add that to the regex with an e flag.
Re: Regex to add text if text is missing
by sk (Curate) on Jun 25, 2005 at 18:55 UTC
    Deleted: Misunderstood the question.