PHP preg_replace certrain strings - php

I have several of these tags in a text document (stored in $content) with a lot of other content as well:
[[tag:author|id:6329]]
And I've been trying to replace all of these tags with a given id (in this case 6329) with another string.
$id = 6329;
$replacement = $this->format($id);
$pattern = "/(\[\[tag:author|id:".$id."\]\])/";
preg_replace($pattern, $replacement, $content);
Although this does not seem to work, and I've been tearing my hair out for the last couple of hours. Can anyone see the error? Many thanks.

You need to escape | too, and not necessary to wrap it with ().
Try:
$pattern = "/\[\[tag:author\|id:".$id."\]\]/";

Related

How do i replace an expression with metacharacters using preg_replace in PHP?

I've tried in different ways, replacing a excerpt of text with metacharacters with another text with metacharacters in PHP. I know, it seems very simple but i've tried many times but didn't get it.
pattern: $Sel = 'anyvalues';
replacement: $Sel = 'one other';
subject: <?php $Sel = 'anyvalues';
I deeply tried using addslashes() and preg_quote() methods in different orders but it doesn't work. I need it to be as represented instead of looking for any workarounds.
Each one of these values lie in different files, i.e., the pattern lies in one file, replacement in another one, and subject in another as well.
Have you wrapped your pattern in delimiters?
$pattern = '$Sel = "anyvalues_containing_delimiter_/";';
$replacement = '$Sel = "one other";';
$subject = '<?php $Sel = "anyvalues_containing_delimiter_/";';
echo preg_replace(sprintf('/%s/', preg_quote($pattern, '/')), $replacement, $subject);
The contents of pattern are the only ones that need escaping, hence the preg_quote call. Second argument is the delimiter in which the pattern is wrapped (what sprintf does here), so any occurences within the pattern content can also be escaped before they are applied.
Edit: I've modified the snippet to cover for occurences of the delimiter within file contents.
Second edit: moved code from linked snippet into the answer itself.

Php, Regex preg_replace_callback

I am using preg_replace_callback, Here is what i am trying to do:
$result = '[code]some code here[/code]';
$result = preg_replace_callback('/\[code\](.*)\[\/code\]/is', function($matches){
return '<div>'.trim($matches[1]).'</div>';
}, $result);
The idea is to replace every match of [code] with <div> and [/code] with </div>, And trim the code between them.
The problem is with this string for example:
$result = '[code]some code[/code]some text[code]some code[/code]';
What i want the result to have 2 separated div's:
$result = '<div>some code</div>some text<div>some code</div>';
The result i get is:
$result = '<div>some code[code]some text[/code]some code</div>';
Now i know the reason, And i understand the regex but i couldn't come up with solution, If anyone know how to make it work i will be very thankful, Thank you all and have a nice day.
Your problem is greedy matchiing:
/\[code\](.*?)\[\/code\]/is
Should behave as you want it to.
Regex Repetition is greedy, which means it captures as many matching items as it can, then gives up one match at a time if it finds that it can't match what's left after the repetition. By using a question mark, you indicate that you want to match non-greedily, or lazily, meaning that the engine will try to match the rest of the regular expression FIRST, then grow the size of the repetition after.
You don't need to use preg_replace_callback() since you can extract the "trimed" content:
$pattern = '~\[code]\s*+((?>[^[\s]++|\s*+(?!\[/code])\[?+)*+)\s*+\[/code]~i';
$replacement = '<div>$1</div>';
$result = preg_replace($pattern, $replacement, $result);

PHP regex title conversion / negative look ahead / toLowerCase

I'm trying to convert some titles in my html pages to <h2>. The pattern is simple.
<?php
$test = "<p><strong>THIS IS A TEST</strong></p><div>And this is Random STUFF</div><p><strong>CP</strong></p>";
$pattern = "/<p><strong>([A-Z ]*?)<\/strong><\/p>/";
$replacement = "<h2>$1</h2>";
$test = preg_replace($pattern, $replacement, $test);
?>
Basically, grab anything that's between <p><strong></strong></p> that is capitalized. Easy enough, so here's the complicated bit.
Firstly, I need to make a single exception. <p><strong>CP</strong></p> must not be converted to <h2>. I tried adding ?!(CP) right after the <p><strong> but it doesn't work.
Secondly, I need to be able to make the first letter capitalized. When I use "ucfirst" with "strtolower" on the preg_replace (ex:ucfirst(strtolower(preg_replace($pattern, $replacement, $test)));), it makes all the characters in the string to lowercase and ucfirst doesn't work as it's detecting "<" to be the first character.
Any hints or am I even going in the right direction?
EDIT
Thanks for the help, it was definitely better to use preg_replace_callback. I found that all my titles were more than 3 characters so I added the limiter. Also added special characters.
Here's my final code:
$pattern = "/<p><strong>([A-ZÀ-ÿ0-9 ']{3,}?)<\/strong><\/p>/";
$replacement = "<h2>$1</h2>";
$test[$i] = preg_replace_callback($pattern, create_function('$matches', 'return "<h2>".ucfirst(mb_strtolower($matches[1]))."</h2>";'), $test[$i]);
Try http://php.net/manual/de/function.preg-replace-callback.php .
You can create a custom function that is called on every match. In this function you can decide to a) not replace CP and b) to not put $1, but ucfirst.
Hope this helps & good luck.

preg_replace with URL problem

I use a preg_replace to auto insert HTML links within paragraphs.
Here's what I currently use:
$pattern = "~(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))(".preg_quote($find_keyword, '/').")\b~msUi";
$replacement = "\$0";
$article_content = preg_replace($pattern, $replacement, stripslashes($article_content), 1, $added );
It works great, except 1 problem:
It doesn't match and replace if the keyword is a URL.
If: $find_keyword="http://www.mysite.com/" it won't come up with any matches even though it's in the content.
I already tried escaping $find_keyword with preg_quote, which didn't make any different.
Any regex experts know a solution? Thanks.
The forward slashes in your $find_keywords are not escaped which is breaking the pattern.
You can run your find_keyword through
$find_keyword=preg_quote("http://www.mysite.com/", '/');
http://www.php.net/manual/en/function.preg-quote.php

PHP replace string help

i am designing a site with a comment system and i would like a twitter like reply system.
The if the user puts #a_registered_username i would like it to become a link to the user's profile.
i think preg_replace is the function needed for this.
$ALL_USERS_ROW *['USERNAME'] is the database query array for all the users and ['USERNAME'] is the username row.
$content is the comment containing the #username
i think this should not be very hard to solve for someone who is good at php.
Does anybody have any idea how to do it?
$content = preg_replace( "/\b#(\w+)\b/", "http://twitter.com/$1", $content );
should work, but I can't get the word boundary matches to work in my test ... maybe dependent on the regex library used in versions of PHP
$content = preg_replace( "/(^|\W)#(\w+)(\W|$)/", "$1http://twitter.com/$2$3", $content );
is tested and does work
You want it to go through the text and get it, here is a good starting point:
$txt='this is some text #seanja';
$re1='.*?'; # Non-greedy match on filler
$re2='(#)'; # Any Single Character 1
$re3='((?:[a-z][a-z]+))'; # Word 1
if ($c=preg_match_all ("/".$re1.$re2.$re3."/is", $txt, $matches))
{
$c1=$matches[1][0];
$word1=$matches[2][0]; //this is the one you want to replace with a link
print "($c1) ($word1) \n";
}
Generated with:
http://www.txt2re.com/index-php.php3?s=this%20is%20some%20text%20#seanja&-40&1
[edit]
Actually, if you go here ( http://www.gskinner.com/RegExr/ ), and search for twitter in the community tab on the right, you will find a couple of really good solutions for this exact problem:
$mystring = 'hello #seanja #bilbobaggins sean#test.com and #slartibartfast';
$regex = '/(?<=#)((\w+))(\s)/g';
$replace = '$1$3';
preg_replace($regex, $replace, $myString);
$str = preg_replace('~(?<!\w)#(\w+)\b~', 'http://twitter.com/$1', $str);
Does not match emails. Does not match any spaces around it.

Categories