Replace only first match using preg_replace
The optional fourth parameter of preg_replace is limit
:
preg_replace($search, $replace, $subject, 1);
Using preg_replace to replace only first match
preg_replace()'s does a Regular Expression match and replace. You are passing it a string instead of a valid RegEx as the first argument.
Instead you might be looking for str_replace() which does string replacement.
Replace first match using preg_replace
In between with regex can be a bit difficult. I recommend using the quantifer \d+
to specify you're looking specifically for a digit character, and use preg_match
to fetch the first result:
<?php
function getFirstGB($str){
if (preg_match("/(\d+)GB/", $str, $matches)) {
return $matches[1];
} else {
return false;
}
}
$str = 'NGM YOU COLOR P550 DUAL SIM 5.5" IPS HD CURVO QUAD CORE 8GB RAM 1GB 4G LTE';
echo getFirstGB($str);
PHP Playground here.
Preg_replace only replaces first match
If you want to clear all br-s inside only one div-block you need to first catch the content inside your div-block and then clear all your br-s.
Your regexp has the only one <br />
in it and so it replaces only one <br />
.
You need something like that:
function clear_br($a)
{
return str_replace("<br />", "", $a[0]);
}
$TEXT = preg_replace_callback("/<div class='quote'>.*?<br \/>.*?<\/div>/is", "clear_br", $TEXT);
PHP: preg_replace only first matching string in array
You may use plain text in the associative array keys that you will use to create dynamic regex patterns from, and use preg_replace_callback
to replace the found values with the replacements in one go.
$internal_message = 'Hey, this is awesome!';
$words = array(
'wesome' => 'wful',
'wful' => 'wesome',
'this' => 'that',
'that' => 'this'
);
$rx = '~(?:' . implode("|", array_keys($words)) . ')\b~';
echo "$rx\n";
$message = preg_replace_callback($rx, function($m) use ($words) {
return isset($words[$m[0]]) ? $words[$m[0]] : $m[0];
}, $internal_message);
echo $message;
// => Hey, that is awful!
See the PHP demo.
The regex is
~(?:wesome|wful|this|that)\b~
The (?:wesome|wful|this|that)
is a non-capturing group that matches any of the values inside, and \b
is a word boundary, a non-consuming pattern that ensures there is no letter, digit or _
after the suffix.
The preg_replace_callback
parses the string once, and when a match occurs, it is passed to the anonymous function (function($m)
) together with the $words
array (use ($words)
) and if the $words
array contains the found key (isset($words[$m[0]])
) the corresponding value is returned ($words[$m[0]]
) or the found match is returned otherwise ($m[0]
).
php preg_replace or expression replace all but first match
I think you can solve this by using preg_replace_callback
and keeping track of keywords you found. I've also added the grouping the @Wiktor Stribiżew suggested, and I personally like to use named-captures in RegEx.
See the comments for additional details
$string = 'gamer thing gamer games test games';
$pattern = '/\b(?<keyword>gamer|games)\b/';
// We'll append to this array after we use a given keyword
$usedKeywords = [];
$finalString = preg_replace_callback(
$pattern,
// Remember to capture the array by-ref
static function (array $matches) use (&$usedKeywords) {
$thisKeyword = $matches['keyword'];
if (in_array($thisKeyword, $usedKeywords, true)) {
return $thisKeyword;
}
$usedKeywords[] = $thisKeyword;
// Do your replacement here
return '~'.$thisKeyword.'~';
},
$string
);
print_r($finalString);
The output is:
~gamer~ thing gamer ~games~ test games
Demo here: https://3v4l.org/j40Oq
How can I make preg_replace only replace the first of *each* character matched?
If you just want a letter to be replaced only once then following regex should work:
echo preg_replace('/([aeiou])(?!.+?\\1)/', '<i>$1</i>', 'alphabet');
OUTPUT:
alph<i>a</i>b<i>e</i>t
PS: Note that it replaces last occurrence of a letter instead of the first one.
EDIT:
Following would produce the same output as expected by the OP (thanks to @AntonyHatchkins):
echo strrev(preg_replace
('/([aeiou])(?!.+?\\1)/', strrev('<i>1$</i>'), strrev('alphabet')))."\n";
EDIT 2:
Upon OP's comment:
Can you help me allow more than one a then? How can I match 2, but not 3 a's
I am posting this answer:
echo strrev(preg_replace('/([aeiou])(?!(.+?\\1){2})/',
strrev('<i>1$</i>'), strrev('alphabetax'))) . "\n";
EDIT 3:
Upon another of OP's comment:
that will allow duplicates for all characters in the string, not just 2 a's & 1 e
I am posting this answer:
echo strrev(preg_replace(array('/(a)(?!(.+?\\1){2})/',
'/(?<!>)([eiou])(?!.+?\\1)/'),
array(strrev('<i>1$</i>'), strrev('<i>1$</i>')), strrev('alphabetaxen')))."\n";
OUTPUT:
<i>a</i>lph<i>a</i>b<i>e</i>taxen
Note: I believe original problem has already changed so many times so please don't add further complexity in this problem. You're free to post another question if you have different queries.
preg_replace on the actual match ( index 1) instead of whole string
I don't know what you want to match with .*
. You don't need it. This will work fine:
preg_replace('/(lets go)/', "going", "lets go somewhere");
Or you can use a lazy match:
preg_replace('/(lets go).*?/', "going", "lets go somewhere");
Explanation: Your original expression was greedy. That roughly means that .*
matches as many characters as possible. .*?
is lazy; it matches the minimum amount of characters.
You can also match 'somewhere' as a sub-pattern, and us it in the replacement:
preg_replace('/(lets go)(.*)/', "going\$2", "lets go somewhere");
Here. $0 is "lets go somewhere", $1 is "lets go", $2 is " somewhere". The backslash is needed because "going\$2" is inside double quotes.
Related Topics
Forget Password Page, Creating a Generated Password to Email to the User
Change Date Format (In Db or Output) to Dd/Mm/Yyyy - PHP MySQL
Cannot Send Session Cookie - Headers Already Sent
Pdo Try-Catch Usage in Functions
Using MySQL Concat() in Where Clause
Php/Symfony/Doctrine Memory Leak
Can't Find Fulltext Index Matching the Column List (Indexes Is Set)
PHP Strtotime "Last Monday" If Today Is Monday
Backslash in PHP -- What Does It Mean
Filling Gaps in Dates Returned from Database - Pure SQL Solution Possible
Get the First or Last Friday in a Month
How to Run Multiple Insert Query in SQL Using PHP in One Go
What Is Normalized Utf-8 All About
Phpmyadmin Automatic Logout Time
How to Add Private Github Repository as Composer Dependency