Preg Replace - replace second occurance of a match
I am relatively new to php, and hope someone can help me with a replace regex, or maybe a match replace I am not exactly sure.
I want to automatically bold the (second occurance of a match) and then make the 4th appearance of a match italic and then the 7th appearance of a match underlined.
This is basically for SEO purposes in content.
I have done some replacements with: and were thinking this should do the trick?
preg_replace( pattern, replacement, subject [, limit ])
I already know the word I want to use in
'pattern' is also a word that is already defined like [word].
`replacement` 'This is a variable I am getting from a mysql db.
'subject' - The subject is text from a db.
Lets say I have this content: This explains more or less what I want to do.
This is an example of the text that I want to replace. In this text I want to make the second occurance of the word example < bold. Then I want to skip the next time example occurs in the text, and make the 4th time the word example appears in italic. Then I want to skip the 5th time the word example appears in the text, as well as the 6th time and lastly wants to make the 7th time example appears in the text underline it. In this example I have used a hyperlink as the underline example as I do not see an underline function in the text editor. The word example may appear more times in the text, but my only requerement is to underline once, make bold once and make开发者_如何学C italic once. I may later descide to do some quotes on the word "example" as well but it is not yet priority.
It is also important for the code not to through an error if there is not atleast 7 occurances of the word.
How would I do this, any ideas would be appreciated.
You could use preg_split
to split the text at the matches, apply the modifications, and then put everything back together:
$parts = preg_split('/(example)/', $str, 7, PREG_SPLIT_DELIM_CAPTURE);
if (isset($parts[3])) $parts[3] = '<b>'.$parts[3].'</b>';
if (isset($parts[7])) $parts[7] = '<i>'.$parts[7].'</i>';
if (isset($parts[13])) $parts[13] = '<u>'.$parts[13].'</u>';
$str = implode('', $parts);
The index formula for the i-th match is index = i · 2 - 1.
The regular expression itself cannot count, and the preg_ functions provide little help. You need a workaround. If you were to actually search for just a word, you might want to use string functions. Otherwise try:
// just counting
if (7 >= preg_match_all($pattern, $subject, $matches)) {
$cb_num = 0;
$subject = preg_replace_callback($pattern, "cb_ibu", $subject);
}
function cb_ibu($match) {
global $cb_num;
$match = $match[0];
switch (++$cb_num) {
case 2: return "<b>$match</b>";
case 4: return "<i>$match</i>";
case 7: return "<u>$match</u>";
default: return $match;
}
}
The trick is to have a callback which does the accounting. And there it's quite easy to add any rules.
That's an interesting question. My implementation would be:
function replace_exact($word, $tag, $string, $limit) {
$tag1 = '<'.$tag.'>';
$tag2 = '</'.$tag.'>';
$string = str_replace($word, $tag1.$word.$tag2, $string, 1);
if ($limit==1) return $string;
return str_replace($tag1.$word.$tag2,$word,$string,$limit-1);
}
Use it like this:
echo replace_exact('Example', 'b', $source_text, 2);
echo replace_exact('Example', 'i', $source_text, 4);
I don't know about how fast this will work, but it will be faster than preg_replace.
精彩评论