up vote 0 down vote favorite

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
...

flag
what have you tried so far .... post something. – Prix Jul 5 at 18:28

4 Answers

up vote 1 down vote accepted

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.

link|flag
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 Jul 5 at 19:44
up vote 0 down vote

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
}
link|flag
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 Jul 5 at 19:47
up vote 0 down vote

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);
}
link|flag
thanks for your input! – HungryCoder Jul 5 at 19:50
up vote 0 down vote

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?

link|flag
Thank you very much for your inputs! – HungryCoder Jul 5 at 19:45
I guess I can use it! My subject is ASCII only! so won't be a problem! – HungryCoder Jul 5 at 19:49

Your Answer

get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.