views:

53

answers:

4

Hello, I need help while trying to spin articles. I want to find text and replace synonymous text while keeping the case the same.

For example, I have a dictionary like:

hello|hi|howdy|howd'y

I need to find all hello and replace with any one of hi, howdy, or howd'y.

Assume I have a sentence:

Hello, guys! Shouldn't you say hello me when I say you HELLO?

After my operation it will be something like:

hi, guys! Shouldn't you say howd'y to me when I say howdy?

Here, I lost the case. I want to maintain it! It should actually be:

Hi, guys! Shouldn't you say howd'y to me when I say HOWDY?

My dictionary size is about 5000 lines

hello|hi|howdy|howd'y go|come
salaries|earnings|wages
shouldn't|should not
...

+1  A: 

I'd suggest using preg_replace_callback with a callback function that examines the matched word to see if (a) the first letter is not capitalized, or (b) the first letter is the only capitalized letter, or (c) the first letter is not the only capitalized letter, and then replace with the properly modified replacement word as desired.

Amber
Amber,Thanks for your answer. I also now believe I will need to use preg_replace with callback. My str_ireplace will replace all instances of the word at once! so I can't maintain proper case of different words! but the 3 conditions that you have suggested, had in my mind earlier :). however, as I did not think about callback function my solution would not be work. so you get the credits :).
HungryCoder
A: 

You can find your string and do two tests:

$outputString = 'hi';
if ( $foundString == ucfirst($foundString) ) {
   $outputString = ucfirst($outputString);
} else if ( $foundString == strtoupper($foundString) ) {
   $outputString = strtoupper($outputString);
} else {
   // do not modify string's case
}
hsz
yep, this is WHAT I am planning to do. but may be different in HOW! :). however, your input will certainly help. thank you very much for your time!
HungryCoder
A: 

Here's a solution for retaining the case (upper, lower or capitalized):

// Assumes $replace is already lowercase
function convertCase($find, $replace) {
  if (ctype_upper($find) === true)
    return strtoupper($replace);
  else if (ctype_upper($find[0]) === true)
    return ucfirst($replace);
  else
    return $replace;
}

$find = 'hello';
$replace = 'hi';

// Find the word in all cases that it occurs in
while (($pos = stripos($input, $find)) !== false) {
  // Extract the word in its current case
  $found = substr($input, $pos, strlen($find));

  // Replace all occurrences of this case
  $input = str_replace($found, convertCase($found, $replace), $input);
}
casablanca
thanks for your input!
HungryCoder
A: 

You could try the following function. Be aware that it will only work with ASCII strings, as it uses some of the useful properties of ASCII upper and lower case letters. However, it should be extremely fast:

function preserve_case($old, $new) {
    $mask = strtoupper($old) ^ $old;
    return strtoupper($new) | $mask .
        str_repeat(substr($mask, -1), strlen($new) - strlen($old) );
}

echo preserve_case('Upper', 'lowercase');
// Lowercase

echo preserve_case('HELLO', 'howdy');
// HOWDY

echo preserve_case('lower case', 'UPPER CASE');
// upper case

echo preserve_case('HELLO', "howd'y");
// HOWD'Y

This is my PHP version of the clever little perl function:

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

Mike
Thank you very much for your inputs!
HungryCoder
I guess I can use it! My subject is ASCII only! so won't be a problem!
HungryCoder