Question

Okay, I got a rather simple one (at least seems simple). I have a multi lined string and I am just playing around with replacing different words with something else. Let me show you...

#!/usr/bin/perl -w
use strict;

$_ = "That is my coat.\nCoats are very expensive.";
s/coat/Hat/igm;
print;

The output would be
That is my Hat
Hats are very expensive...

The "hat" on the first line shouldn't be capitalized. Are there any tricks that can make the casing compliant with how english is written? Thanks :)

OTHER TIPS

You can use the e modifier to s/// to do the trick:

s/(coat)/ucfirst($1) eq $1 ? 'Hat' : 'hat'/igme;

For one, you should use \b (word boundary) to match only the whole word. For example s/hat/coat/ would change That to Tcoat without leading \b. Now for your question. With the flag /e you can use Perl code in the replacement part of the regex. So you can write a Perl function that checks the case of the match and then set the case of the replacement properly:

my $s = "That is my coat.\nCoats are very expensive.";
$s =~ s/(\bcoat)/&same_case($1, "hat")/igme;
print $s, "\n";

sub same_case {
        my ($match, $replacement) = @_;

        # if match starts with uppercase character, apply ucfirst to replacement
        if($match =~ /^[A-Z]/) {
                return ucfirst($replacement);
        }
        else {
                return $replacement;
        }
}

Prints:

That is my hat.
Hats are very expensive.

This may solve your problem:


#!/usr/bin/perl -w

use strict;

sub smartSubstitute {
    my $target = shift;
    my $pattern = shift;
    my $replacement = shift;

    $pattern = ucfirst $pattern;
    $replacement = ucfirst $replacement;

    $target =~ s/$pattern/$replacement/gm;

    $pattern = lcfirst $pattern;
    $replacement = lcfirst $replacement;

    $target =~ s/$pattern/$replacement/gm;

    return $target;
}

my $x = "That is my coat.\nCoats are very expansive.";
my $y = smartSubstitute($x, "coat", "Hat");
print $y, "\n";
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top