PHP String Replace Match Whole Word

PHP string replace match whole word

You want to use regular expressions. The \b matches a word boundary.

$text = preg_replace('/\bHello\b/', 'NEW', $text);

If $text contains UTF-8 text, you'll have to add the Unicode modifier "u", so that non-latin characters are not misinterpreted as word boundaries:

$text = preg_replace('/\bHello\b/u', 'NEW', $text);

PHP string replace match whole word in array

this should work for you

$arrWords = array(
"cat" => "dog",
"dog" => "mouse",
"phone" => "book"
);

$txttest = "My catalogue has a cat and a phone";
$stringArr = explode(' ',$txttest);

foreach($stringArr as $k=>$v){
if(array_key_exists($v,$arrWords)){
$stringArr[$k]=$arrWords[$v];
}
}
echo implode(' ',$stringArr);

EDIT

As per the given situation to replace the string

My catalog has a cat and a phone

using the following array to match the keys and replace with the respective values

$arrWords = array(
"cat" => "dog",
"dog" => "mouse",
"phone" => "book"
);

As there are specific values that are matching the keys there is a strong possibility that our replacement string could be substituting each other if we use preg_replace within a for loop for above array,

possible suspects ("cat" => "dog","dog" => "mouse")

A better alternative, in this case, is preg_replace_callback with word boundary \b for such requirements as there could be special characters too inside the string other than words like \t i.e TAB or any other.

so ideally the original solution provided above should not (in fact never) be used and isn't really a solution as it would fail when there are special characters.

What actually should be done is to first create a regular expression which

should use word boundary with a capturing group inside containing
all the words to be matched as alternatives(using OR operator).

So if I convert my above statement into a regular expression keeping in mind the given search&replace array $arrWords it would be like.

/\b(cat|dog|phone)\b/gi

the g modifier, in the end, is the global pattern flag which assures all matches (don't return after the first match) and i for the case-insensitive match. We can omit g modifier when using in preg_replace_callback() function as the 4th parameter of this function will take care of it.

So if I add my regex to any online regex utility and provide a string like

My catalog has a cat cat cat cat a\tdog and a phone

(notice that using online utility you should remove the \t with actual TAB when writing the string to the regex editors online to be detected as a special character or \t)

it will highlight all the matches found like below

My catalog has a cat cat cat cat a dog and a phone

(the spaces after a are because of the TAB)
Now they need to be replaced and after replacing the above statement should be converted to

My catalog has a dog dog dog dog a mouse and a book

so now comes the preg_replace_callback() and the callback function that will do the trick of replacing and also taking care of not swapping/substituting replacement keys.

$r = preg_replace_callback(
"/\b(".implode("|",array_keys($arrWords)).")\b/i",
function($matchingPharse) use ($arrWords) {
return strtolower($arrWords[strtolower($matchingPharse[0])]);
},
$txttest
);

What we are doing here is that in the first parameter we are making the same regex above by using array_keys() to extract the words to be matched in the string from the given array ,as preg_replace_callback() finds the matching words in the string, it passes them to the callable anonymous function in the second parameter and returns the replacement words for those matches in the replacement array $arrWords only one thing new is use keyword, as we need to access the $arrWords array and return the respective values from the matched keys and the callback function has only one parameter matches so the easiest way to pass more than one parameters to the callback function is with the 'use' keyword. I got the idea about it from here under section User Contributed Notes.

So the above will output

My catalog has a dog dog dog dog a mouse and a book

and if we need to check that it preserves the case-insensitivity we need to add the i feed

INPUT

The cat's mouse(named Mouse), cat (named Cat), and dog (named Giraffe) are in this catalog.

OUTPUT

The dog's mouse(named Mouse), dog (named dog), and mouse (named Giraffe) are in this catalog.

Another case provided by senior member was

$arrWords=["cat"=>"dog","dog"=>"mouse","mouse"=>"Mickey"];

INPUT

The cat's mouse(named Mouse), cat (named Cat), and dog (named Giraffe) are in this catalog.

OUTPUT

The dog's mickey(named mickey), dog (named dog), and mouse (named Giraffe) are in this catalog.

I had a discussion with one of the senior members of the community and he guided me about the severity of misinformation in the original answer that could guide others in the wrong direction which neither SO, me or any other member of this community intend to do, so I tried to improve the answer and would request the OP owner to follow this approach if he intended to use my previous answer. And I apologize for providing a poor solution at the start.

using str_replace to match whole words /case insensitive

For the whole-words issue, there is a solution here using preg_replace(), and your the solution would be to add /\b to the beginning and \b/u to the end of your array-values. The case-insensitive could be handled with preg_replace_callback (see example #1), but if you are working with a small array like your example, I would just recommend duplicating the array-values.

Applied to your example:

$array2 = array(
'/\bis\b/u',
'/\bof\b/u',
'/\bto\b/u',
'/\bpage\b/u',
'/\bIS\b/u',
'/\bOF\b/u',
'/\bTO\b/u',
'/\bPAGE\b/u'
);

$text = "homepage-of-iso-image";
echo $text1 = preg_replace($array2,"",$text);

str_replace: Match whole word only

You don't need the word boundary on the start of your string:

$str = preg_replace('/:Name\b/i', '"Test"', $str);

str_replace replace only match words

Update:

HD, thank you! your solution works for me!

This is work version

function replace_text_wps($text){

$dir = plugin_dir_path( __FILE__ );
$file= $dir."bad2.list";

$badlist = file($file, FILE_IGNORE_NEW_LINES);

$replacement = "[CENSORED]";
$badlist = array_map(function($v) { return "\b". $v ."\b"; }, $badlist);
foreach($badlist as $f) {
$text = preg_replace("/".$f."/u", $replacement, $text);


return $text;
}

PHP str-replace whole word from array

Try using RegEx to strip hashtags. You can use preg_replace function, e.g.

$tags = implode('|', $tagsArray);
$noTags = preg_replace('/\#(' . $tags . ')\b/i', '', $instagramText);

So actually it'll be:

$noTags = preg_replace('/\#(hashtag|hash|myword|another|hashing)\b/i', '', $instagramText)
// result:
" ! Lorem Ipsum dolor sit ament. "

This way it strips all words (with \b word boundary metacharacter) starting with # char.

Hope it helps.

EDIT

Use preg_replace_callback to check if matched hashtag is starting with uppercase, like:

preg_replace_callback(
'/\ ?#(' . $tags . ')\b ?/i',
function($matches) {
return is_first_uppercase($matches[1]) ? str_ireplace('#' . $matches[1], $matches[1], $matches[0]) : '';
},
$instagramText
);

You just need to implement is_first_uppercase function, for example like this

With:

"#Hashtag ! Lorem Ipsum #Dolor sit ament. #hash #myword #another #hashing"

It should produce:

"Hashtag ! Lorem Ipsum Dolor sit ament."

PHP Array str_replace Whole Word

A possible approach using regular expressions would/could look like this:

$result = preg_replace(
'/\b(tag_name_item(_category)?)\b/',
'$1' . $suffix,
$string
);

How it works:

  • \b: As you say are word boundaries, this is to ensure we're only matching words, not word parts
  • (: We want to use part of our match in the replacement string (tag_name_index has to be replaced with itself + a suffix). That's why we use a match group, so we can refer back to the match in the replacement string
  • tag_name_index is a literal match for that string.
  • (_category)?: Another literal match, grouped and made optional through use of the ? operator. This ensures that we're matching both tag_name_item and tag_name_item_category
  • ): end of the first group (the optional _category match is the second group). This group, essentially, holds the entire match we're going to replace
  • \b: word boundary again

These matches are replaced with '$1' . $suffix. The $1 is a reference to the first match group (everything inside the outer brackets in the expression). You could refer to the second group using $2, but we're not interested in that group right now.

That's all there is to it really


More generic:

So, you're trying to suffix all strings starting with tag_name, which judging by your example, can be followed by any number of snake_cased words. A more generic regex for that would look something like this:

$result = preg_replace(
'/\b(tag_name[a-z_]*)\b/',
'$1' . $suffix,
$string
);

Like before, the use of \b, () and the tag_name literal remains the same. what changed is this:

  • [a-z_]*: This is a character class. It matches characters a-z (a to z), and underscores zero or more times (*). It matches _item and _item_category, just as it would match _foo_bar_zar_fefe.

These regex's are case-sensitive, if you want to match things like tag_name_XYZ, you'll probably want to use the i flag (case-insensitive): /\b(tag_name[a-z_]*)\b/i

Like before, the entire match is grouped, and used in the replacement string, to which we add $suffix, whatever that might be

str_replace with whole words only

You have one extra space so you need to trim to remove space. so before query use trim() to remove space and match exact word in query.

$street_only = trim($street_only);

Replace whole word only with or without regex

\b refers only to word boundaries in an ASCII perception. Also . is a character of special meaning in regular expression — meaning "match any single character (except newline)"

If the "needle" may contain special characters, use preg_quote() and create DIY boundaries.

preg_quote() takes str and puts a backslash in front of every character that is part of the regular expression syntax. 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.

$str = preg_replace("~(?<=^| )" . preg_quote($needle, "~") . "(?= |$)~", 'God', $str);


Related Topics



Leave a reply



Submit