tags:

views:

108

answers:

4

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 :)

+1  A: 

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.
jkramer
+4  A: 

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

s/(coat)/ucfirst($1) eq $1 ? 'Hat' : 'hat'/igme;
eugene y
Not a complete solution, but it covers 'coat' and 'Hat'
Axeman
Clever solution!
David
+5  A: 

see how-to-replace-string-and-preserve-its-uppercase-lowercase

For more detail go to How do I substitute case insensitively on the LHS while preserving case on the RHS?

Nikhil Jain
I didn't realize this was already ask :|
David
@Davidmoreen : never mind :-)
Nikhil Jain
A: 

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";
Siu Ching Pong - Asuka Kenji