0

I have a number of sentences where I want to replace each one with a single word, this word (or a variant of it) is contained in the sentence. I put my regex patterns in an indexed array which are single words to find in each string. I have a second array which have the replacement words (These words are just simple examples):

$pattern = array('/one/','/two/','/three/');
$replacements = array('ones','twos','threes');

Say for example I have the sentence:

"There is one tree"

Then I want to replace the sentence with

"ones"

I have tried both preg_replace and preg_replace_calback and are not sure which one to use or whether I should use preg_match

I am trying this:

$simplified = preg_replace_callback($pattern, function($matches) {
      return $replacements[array_search($matches[0], $pattern, true)];
}, $simplified, 1);

where $simplified contains the word which I want to replace the sentence with.

I believe that array_search is applicable for associated arrays but I tried looping through the indexed array as well. I have to find the regex that actually matched the word in the sentence and need to get the index of that match to find the correct word in the replacement array. This is long winded and could be the wrong approach.

My questions are: 1. Am I approaching this wrong? 2. If this approach can work, how do I get the sentence replaced with a single word?

jmarais
  • 93
  • 4
  • 14
  • Are those replaces your actual replaces? You'd just need to add an `s` to the match, within the replace if so, like [this](http://regex101.com/r/tP3sR1). – Jerry Feb 09 '14 at 15:58
  • I struggled a bit to explain exactly what I am trying to do, an actual example text is: "3 Pack of Vests", In both instances where the word vest or vests are contained in the sentence I want to replace the sentence with the single word "Vests". – jmarais Feb 09 '14 at 16:05

1 Answers1

0

preg_replace_callback() is not suitable for this task - for every match in the regex, it calls a function that is passed the match text as a parameter. You do not want that. Use preg_match() instead.

First, create an associative array with pattern strings as the keys and the replacement strings as the values. Loop through the combined array, check if the pattern matches the string - if it does, replace the entire word with the corresponding $replacement and exit the loop.

Code:

$string = "There is one tree"; 

$patterns = array('one','two','three');
$replacements = array('ones','twos','threes');
$combined = array_combine($patterns, $replacements);

foreach ($combined as $pattern => $replacement) {
    $pattern = sprintf('/\b%s\b/', preg_quote($pattern, '/'));
    if (preg_match($pattern, $string)) {
        $string = $replacement;
        break;
    }
}

echo $string; // => ones

Notes:

  • sprintf() is just used to create the pattern string
  • preg_quote() to properly escape regular expression characters. This is useful if you have a run-time string that you need to match in some text and the string may contain special regex characters.
  • \b is a metacharacter that matches at any word boundary. Phrased differently, \b matches the empty string at the beginning or end of a word. The match is zero-length, meaning it does not consume any characters

For more information about preg_replace_callback(), I suggest you read this answer. It describes the working of preg_replace_callback very briefly. The documentation for preg_replace_callback() is great, too.

Community
  • 1
  • 1
Amal Murali
  • 75,622
  • 18
  • 128
  • 150