tags:

views:

201

answers:

4

Perl question:

I want to replace one string with the other; both are of the same length. I want to replace all occurrences of the string (case insensitive), but I want that the case of the letter will be preserved. So if the first letter was upper case, the first letter after the replacement will be upper case also.

For example, if I want to replace "foo" with "bar", so I want that

foo ==> bar
Foo ==> Bar
FOO ==> BAR

Is there a simple way to do this in Perl?

Thanks.

A: 

Check character by character, if character's ASCII value falls in uppercase ASCII values replace with uppercase else lowercase.

Nitin Chaudhari
+1  A: 

Don't you just hate people who answer the question that you didn't asking?

Sorry, I'm not that much of a regular expression guru (nor even Perl), so all that I can offer is a clumsy algorithm.

You know each string is the same length, so basically, you can

index = Pos(string, oldString)
for i = index to index + strlen(oldString)
  if (oldString[i] >= 'a') && (oldString[i] <= 'z'')
    string[i] = ToLower(newString[i])
  else
    string[i] = ToUpper(newString[i])0x20

I do realize that this is not your ideal solution, and offer it only as a last ditch fallback, so please don't downvote me if you don't like it (I am trying to help). Thanks.

LeonixSolutions
thanks for the answer. I thought of this kind of solution also, just wanted to know if there is "shorter" way...
eran
+12  A: 

This might be what you are after:

How do I substitute case insensitively on the LHS while preserving case on the RHS?

This is copied almost directly from the above link:

sub preserve_case($$) {
    my ($old, $new) = @_;
    my $mask = uc $old ^ $old;
    uc $new | $mask .
    substr($mask, -1) x (length($new) - length($old))
}

my $string;

$string = "this is a Foo case";
$string =~ s/(Foo)/preserve_case($1, "bar")/egi;
print "$string\n";

# this is a Bar case

$string = "this is a foo case";
$string =~ s/(Foo)/preserve_case($1, "bar")/egi;
print "$string\n";

# this is a bar case

$string = "this is a FOO case";
$string =~ s/(Foo)/preserve_case($1, "bar")/egi;
print "$string\n";

# this is a BAR case
Mike
+1 for pointer to FAQ. Note that the posted solution only works for ASCII due to of bitwise-xor. The FAQ also offers a more robust (but longer and slower) alternative.
Michael Carman
A: 

Here is the doc :

M42