Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Regex Substitution Evaluations

by mobiusinversion (Beadle)
on Jul 05, 2008 at 19:53 UTC ( [id://695736]=perlquestion: print w/replies, xml ) Need Help??

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

Dearest Monks,

Please consider the following code:
use strict; my $my_name = "august ferdinand mobius"; $my_name =~ s/\b(\w)/\U$1/g; print $my_name; #prints August Ferdinand Mobius
I am trying to create a subroutine that consumes a string, a pattern, a replacement and a modifier (perhaps limited to one or more of 'igsx') and returns the result of a substitution:
sub replace { my($text, $pattern, $replacement, $modifiers) = @_; (my $result = $text) =~ s/$pattern/$replacement/$modifiers; return $result; }
I would like to call such a subroutine as follows:
$my_name = replace("august ferdinand mobius","\b(\w)","\U$1","igs");
Of course, the above doesn't work. But I have tried many other ways, e.g. using eval, s///ge, s///gee, etc.

I have attempted to do my homework using the Owl, Camel and Ram books, plus the perldoc, but I am totally stumped. Any help would be greatly appreciated.

Update: 13:06 PST
This appears to work:
use strict; my $x = "august ferdinand mobius"; my $y = replace($x, '\b(\w)', '\U$1', 'igs'); print $y; sub replace { my($text, $pattern, $replacement, $modifiers) = @_; my $result = ''; eval '($result = $text)'."=~ s/$pattern/$replacement/$modifiers"; return $result; }
It does however, to my mind, open security problems due to the eval'ing - which I hope is unnecessary with a more elegant solution. Besides security, will this fail on certain edge cases? (besides non-escaped members of the dirty dozen, which I'm handling now)

Replies are listed 'Best First'.
Re: Regex Substitution Evaluations
by pc88mxer (Vicar) on Jul 05, 2008 at 20:27 UTC
    Evaling strings is fraught with numerous pitfalls, and I would avoid that approach. Most modifiers can also be expressed directly in the regular expression. E.g.:
    m/foo/i; # -> m/(?i)foo/; m/bar/m; # -> m/(?m)bar/; ...
    See perldoc perlre for more details. So either add them yourself, or require that the caller do so.
      Please refer to my original post.

      As you can see, I would absolutely like to avoid using eval, and I have consulted perldoc's perlre perlop perlretut and perlreref entries several times.

      How might you suggest going about substitutions?

        I think pc88mxer answered your question for the most part.

        $my_name = replace("august ferdinand mobius","\b(\w)","\U$1","igs"); # Becomes something more like... $my_name = replace("august ferdinand mobius", qr/(?igs)\b(\w)/, '\U$1' +);

        Update: You should consider that your solution will not work for a variety of names, like mccleod, vomdorp, decaro, etc. For proper names, a dictionary (with the right library under it, like proper names) is a better way to go, and there is no perfect solution since the same spellings are sometimes capitalized differently. :(

Re: Regex Substitution Evaluations
by ikegami (Patriarch) on Jul 05, 2008 at 23:41 UTC
    If the capture works, I'd use:
    sub replace { my($text, $pattern, $replacement, $global) = @_; my $result = $text; if ($global) { $result =~ s/$pattern/$replacement/eg; } else { $result =~ s/$pattern/$replacement/e; } return $result; } my $y = replace($x, qr/\b(\w)/is, '"\U$1"', 1);

    Keep in mind the 3rd argument is arbitrary Perl code instead of a string literal. It used to be able to include arbitrary Perl code, so nothing's new on the (lack of) security front.

    If you really do want the options and/or regexp to be a string, I'd use my previously posted solution.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://695736]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-25 21:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found