str_replace not working 100%

I am using this code to replace hashtags in the message:

$post['message'] = "Free:
#SocialMedia  #Facebook, #Twitter, #GooglePlus
#Forum #blog

Paid
 #GoogleAdwords #FacebookAds, #TwitterAds #marketing";

preg_match_all('/#([\w]+)/i', $c, $matches);
foreach ($matches[0] as $hashtag)
{
//remove # symbol    
$hashtag_stripped = str_replace('#', '', $hashtag);

//check lenght
if ($hashtag && strlen($hashtag_stripped) >= 3)
{    

//replace hash tags    
$post['message'] = str_replace($hashtag, '[url='.$mybb->settings['bburl'].'/hashtag/'.$hashtag_stripped.']'.$hashtag.'[/url]', $post['message']);
}
}

The problem is that I am not sure why it doesn’t work on these tags:

#FacebookAds, #TwitterAds

Only Replaces #Facebook and #Twitter

The preg_match returns correct tags:

#SocialMedia 
#Facebook 
#Twitter 
#GooglePlus 
#Forum 
#blog 
#GoogleAdwords 
#FacebookAds 
#TwitterAds 
#marketing 

But for some reason str_replace fails to match the entire word!

  1. I’d use /#(\w+)/i as RegExp
  2. I’d use $matches[1] as that already excludes the # sign
  3. $hashtag cannot be empty

Thanks buddy for your reply! What do you mean by:

  1. $hashtag cannot be empty

He means this

if ($hashtag

is always true because $hashtag comes from matches array which doesn’t contain empty items

I am using this in my code is this OK:

if ($hashtag && strlen($hashtag_stripped) >= 3)

there’s no need for that. you can include that condition into the RegExp: /#(\w{3,})/

Thanks buddy so much. I am not sure case preg_match returns correct tags but they are not getting replaced correctly with the str_replace

I notices it happens when you add to many blank spaces. You can see the message I posted contains a ton of blank spaces if you remove then it works OK.

Any ideas?

preg_replace instead. Do the entire block of code in a single line.

$post['message'] = preg_replace("~#(\w{3,})~","[url=".$mybb->settings['bburl']."/hashtag/$1]$0[/url]",$post['message']);
1 Like

@StarLion buddy your solution worked OMG thanks so much :smile:

I am sorry one more question please?

How can I incorporate this:

// strip color, bbcode and html
     $a = strip_tags($post['message']);
     $pattern_bbcode = '#\[(?<start>[^\s\]=]*)[^\]]*].*?\[\/\k<start>\]#s'; 
     $pattern_color = '/color:(.*?);.*/';
     $replace = '';
     $b = preg_replace($pattern_bbcode, $replace, $a);
     $c = preg_replace($pattern_color, $replace, $b);
     
     //Remove any BBcode left
     $c = preg_replace('#\[[^\]]+\]#', '', $c);

Into this:

$post['message'] = preg_replace("~#(\w{3,})~","[url=".$mybb->settings['bburl']."/hashtag/$1]$0[/url]",$post['message']);

The problem is my message can contain BBCode, or HTML and CSS like color that looks like hash tag!

Dont understand what you mean by incorporating Apple into Orange.

What exactly do you want it to do?

The code you shared works! The thing is it will parse anything that has # symbol this means that bbcode color and HTML css color will be made into hash tag I don’t want that.

This is what I don’t want to grab.

color:#xxx;
font=#xxx
#xxx;

So how do you distinguish whether the #123 i just put in is a hashtag or a color code? Regex does not use context.

Well if you can match this pattern:
color:#333; then don’t use

$pattern_color = '/color:(.*?);.*/';

it could work with a RegExp lookbehind (but I’ve never used one myself).

OK buddy thanks a lot maybe someone has more experience thanks anyways.

Well, lookbehinds would work for the first two cases, but…how are you gonna determine the third?

$match[0] is an array right! Is there a way to somehow take the message and replace in it each value from array $match[0]?

Some like this but I can’t figure how to grab the word that it’s replacing for the anchor link:

$post['message'] = str_replace(array('#GooglePlus', '#Twitter'), '[url='.$mybb->settings['bburl'].'/hashtag/0]0[/url]', $post['message']);

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.