Countach
Countach

Reputation: 607

preg_replace a hashtag that doesn't end with ;

I am currently using preg_replace to replace hashtags mentioned with html links like shown below. The issue is there is a possibility there will be html code as well being checked. So some css such as color: #000000; will force it to try convert that hex code into a link.

I basically need my regex to ignore doing any preg_replace if the last letter of a word is ;. Here's what I currently have:

$str = preg_replace('/#([a-zA-Z0-9!_%]+)/', '<a href="http://example.com/tags/$1">#$1</a>', $str);

Example input: 'I like #action movies!'
Expected output: I like <a href="http://example.com/tags/action">#action</a> movies!'

I cannot use the end of the string to check this as chunks of text is checked at any given time so the string supplied could be #computer text text text #computer for instance.

Appreciate any assistance.

Upvotes: 1

Views: 394

Answers (5)

Kumar
Kumar

Reputation: 1217

Well, You can use below code, Actually I am new to regex so it is not that professional but it works, here it is

$data = "<p style='color:#00000;'>Heloo</p> #computer text text text #computer #say #goo1d #sd! #say_hello";
echo preg_replace("/(?<!\:)(\s+)\#([\w]+)(?!\;)/",'<a href="http://example.com/tags/$2">#$2</a>',$data);

This expression I have use

/(?<!\:)(\s+)\#([\w]+)(?!\;)/

Output is

<p style='color:#00000;'>Heloo</p> <a href="http://example.com/tags/computer">#computer</a> text text text <a href="http://example.com/tags/computer">#computer</a> <a href="http://example.com/tags/say">#say</a> <a href="http://example.com/tags/goo1d">#goo1d</a> <a href="http://example.com/tags/sd">#sd</a>! <a href="http://example.com/tags/say_hello">#say_hello</a>

I hope it helps someone.

Upvotes: 0

Ibrahim
Ibrahim

Reputation: 6088

This regex should work:

#([\w!%]+(?=[\s,!?.\n]|$))

Demo: https://regex101.com/r/KrRiD3/2

Your PHP code:

$str = 'I like #strategy games #f1f1f1; #e2e2e2; #action games!';
$str = preg_replace('/#([\w!%]+(?=[\s,!?.\n]|$))/', '<a href="http://example.com/tags/$1">#$1</a>', $str);
echo $str;

output:

I like #strategy games #f1f1f1; #e2e2e2; #action games!

Upvotes: 0

phobia82
phobia82

Reputation: 1257

In your regex you can check if next to your hashtag there is a ;, non alphanumeric, end of line or end of string:

/#([a-zA-Z0-9!_%]+)([^;\w]{1}|$)/

Then use $1 and $2 accordingly

'<a href="http://example.com/tags/$1">#$1</a>$2'

Your code will look like

$str = preg_replace('/#([a-zA-Z0-9!_%]+)([^;\w]{1}|$)/', '<a href="http://example.com/tags/$1">#$1</a>$2',$str);

Here you can see some tests: https://regex101.com/r/yN4tJ6/65

Upvotes: 1

user6269864
user6269864

Reputation:

you can add a condition to check last string is ; or not and use it accordingly . Example :

if (substr($str, -1)==';'){
//do nothing 
}
else {
$str = preg_replace('/#([a-zA-Z0-9!_%]+)/', '<a href="http://example.com/tags/$1">#$1</a>', $str);
}

Hope this help .

Upvotes: 0

Shai Shprung
Shai Shprung

Reputation: 146

Until a regEx guru come to your rescue (if ever...) and because you are in PHP; here is a solution with few lines of code.

$str="hi #def; #abc #ghi"; // just a test case (first one need be skipped)

if (preg_match_all('/#([a-zA-Z0-9!_%]+.?)/', $str,$m)){
   foreach($m[1] as $k) if(substr($k,-1)!=';') {
      $k=trim($k);
      $str=str_replace("#$k","<a href='http://wxample.com/tags/$k'>#$k</a>",$str);
    }
}

print "$str\n";

Upvotes: 1

Related Questions