php: preg_match and preg_replace - php

I'm unsure of how to do the following...
I need to search through a string and match all instances of a forward slash and certain letters. This is for word modifications that users have the ability to input and I want them to be able to modify individual words.
Here is an example string
Hello, isn't the weather just absolutely beautiful today!?
What I'd like the user to be able to do is something like this
Hello, isn't the /bo weather just /it beautiful today!?
take note of the /bo and /it
what I'd like to do is have a preg_match and or preg_replace statement that finds and replaces the instances of /bo and /it and converts them instead into html tags such as bolded html tag and italics html tag (i cant type them here or they get converted into actual html. but wrap themselves around the word immediately following the /bo so in this example it would wind up being
Hello, isn't the <b>weather</b> just <i>beautiful</i> today!?
Any ideas how I could do this with a regex?
Once the conversions are done i'll do the standard sanitizing before inserting the data into the database along with prepared statements.

$string = "Hello, isn't the /bo weather just /it beautiful /bo today!?";
var_dump(preg_replace (array('/\/bo\s(\w+)/', '/\/it\s(\w+)/'), array('<b>$1</b>', '<i>$1</i>'), $string));
"Hello, isn't the weather just beautiful today!?"

You can use preg_replace_callback for this purpose.
This basically calls a callback method for every match that occurs.
Inside the callback, you can perform the replacement according to your conditions(bold for bo, italics for it, heading for he et al.)
Something like this -
$str = "Hello, isn't the /bo weather just /it beautiful today!?";
$regex = "/\/(.*?)\s+(.+?)\b/";
function callback($matches){
$type = $matches[1];
$text = $matches[2];
switch($type){
case "bo":
return "<b>".$text."</b>";
break;
case "it":
return "<i>".$text."</i>";
break;
default:
return $text;
}
}
$resp = preg_replace_callback(
$regex,
"callback",
$str
);
var_dump($resp);
/*
OUTPUT-
Hello, isn't the <b>weather</b> just <i>beautiful</i> today!?
*/
This example could be extended further by checking for various types and invalid types

The regexp
/\/(bo|it)\s+([\S]+)(?=\b)/g
and replacement string
<$1>$2</$1>
would almost do it:
Hello, isn't the <bo>weather</bo> just <it>beautiful</it> today!?
But the tags are not quite right yet ... They need to be single letters. :-(
Try here: https://regex101.com/r/oB9gT0/1
2. Edit - a bit late, but now it works:
$str=preg_replace('/\/([bi])((?<=b)o|(?<=i)t)\s+([\w]+)/','<$1>$3</$1>',$str);
will now deliver the correct result:
Hello, isn't the <b>weather</b> just <i>beautiful</i> today!?
see here: https://regex101.com/r/oB9gT0/3

Related

php - Replace Template Code with HTML

I got a Button, that creates this template code
[5afc4076e9f1b1526481014.pdf]##LINKNAME## (96.51 kb)
The filename and file size vary und the user can change the ##LINKNAME##, as well.
This code goes to a database and when I get it back, I want to replace it to
##LINKNAME## <i>(96.51 kb)</i>
I think I need to use preg_replace() but I am not really good at regular expressions.
I stopped here:
<?php
$string = ' [5afc4076e9f1b1526481014.pdf]##LINKNAME## (96.51 kb)';
$regex = '[[a-zA-Z0-9]+.pdf](.*?)\s';
$replace = 'I DONT KNOW';
echo preg_replace($regex, $replace, $string);
?>
I know that this is a complete mess, but I'm not getting any results as long as I don't know the regex and the correct $replace.
Regex: ^\[([^\]]+)\](\w+)\s\(([^)]+)\)$
Replace with: \2<i>(\3)</i>
Demo

PHP regex replace between wordpress shortcode tag

I have a shortcode which I want to be able to strip away depending on the context of the post. Eg.
[tooltip slug="test"]Test Text[/tooltip]
I would like the output to be:
<span class="dummy">Test Text</span>
I have experimented (a lot!) with preg_replace and I can't seem to get it to recognize that the replacement string is between the ']' and then delimited by '[/tooltip]' without doing multiple passes.
Ideas?
Update: As so often happens, about 10 seconds after I wrote this one of my attempts seemed to work. I don't think it's as good as the solution below but FWIW...
$my_var .= preg_replace('/(?:\[tooltip slug=\"([^\"]*)"[^\>]*\]([^\<]*)\[\/tooltip\])/', '<span class="dummy">\\2</span>', $my_post->post_content);
Here is the simple regex you are looking for.
$result = preg_replace('%\[tooltip slug="[^"]*"]([^[]*)\[/tooltip]%',
'<span class="dummy">\1</span>', $subject);
What we do here is capture the text between the tooltip tags, and insert it in the replacement.
Let me know if you need any details.
$test = preg_match('/\[([^\]]+)\]([^\[]+)\[/', '[tooltip slug="test"]Test Text[/tooltip]', $matches);
echo $matches[2];

searching link with php regular expression

I was using c and c# for programming and I am using some third-party regular expression library to identify link pattern. But yesterday, for some reason, someone asked me to use php instead. I am not familiar with the php regular expression but I try, didn't get the result as expected. I have to extract and replace the link of an image src of the form :
<img src="/a/b/c/d/binary/capture.php?id=main:slave:demo.jpg"/>
I only want the path in the src but the quotation could be double or single, also the id could be vary form case to case (here it is main:slave:demo.jpg)
I try the following code
$searchfor = '/src="(.*?)binary\/capture.php?id=(.+?)"/';
$matches = array();
while ( preg_match($searchfor, $stringtoreplace, $matches) == 1 ) {
// here if mataches found, replace the source text and search again
$stringtoreplace= str_replace($matches, 'whatever', $stringtoreplace);
}
But it doesn't work, anything I miss or any mistake from above code?
More specifically, let say I have a image tag which give the src as
<img src="ANY_THING/binary/capture.php?id=main:slave:demo.jpg"/>
here ANY_THING could be anything and "/binary/capture.php?id=" will be fixed for all cases, the string after "id=" is of pattern "main:slave:demo.jpg", the string before colon will be changed from case to case, the name of the jpeg will be varied too. I would expect to have it replaced as
<img src="/main/slave/demo.jpg"/>
Since I only have right to modify the php script at specific and limit time, I want to debug my code before any modification made. Thanks.
First of all, as you may know, regex shouldn't be used to manipulate HTML.
However, try:
$stringtoreplace = '<img src="/a/b/c/d/binary/capture.php?id=main:slave:demo.jpg"/>';
$new_str = preg_replace_callback(
// The regex to match
'/<img(.*?)src="([^"]+)"(.*?)>/i',
function($matches) { // callback
parse_str(parse_url($matches[2], PHP_URL_QUERY), $queries); // convert query strings to array
$matches[2] = '/'.str_replace(':', '/', $queries['id']); // replace the url
return '<img'.$matches[1].'src="'.$matches[2].'"'.$matches[3].'>'; // return the replacement
},
$stringtoreplace // str to replace
);
var_dump($new_str);

preg_match (I can't do regex)

The company I work for have asked me to give them the ability to place a modal box on the web page from the CMS, but do not want to type HTML. As I cannot for the life of me understand regex I can't get it.
The layout of the code they should type is this:
++modal++
Some paragraph text.
Another paragraph.
++endmodal++
The paragraphs are already converted by markdown into <p>paragraph</p>.
So really the match has to be ++modal++ any number of A-Za-z0-9any symbol excluding + ++endmodal++ then replaced with HTML.
I'm not sure it preg_match or preg_replace should be used.
I got this far:
$string = '++modal++<p>Hello</p>++endmodal++';
$pattern = '/\+\+modal\+\+/';
preg_match($pattern, $string, $matches);
Thank you in advance.
EDIT: A to be a bit more clear, I wish to replace the ++modal++ and ++endmodal++ with HTML and leave the middle bit as is.
I don't really think you need a RegEx here as your delimiters remain always the same and always on the same position of the string. Regular expressions are also expensive on resources and as a third counter argument you said you're not fit with them.
So why not use a simple replacement or string trimming if it comes to that.
$search = array('++modal++', '++endmodal++');
$replacement = array('<tag>', '</tag>');
$str = '++modal++<p>Hello</p>++endmodal++';
$result = str_replace($search, $replacement, $str);
Where, of course, '<tag>' and '</tag>' are just example placeholders for your replacement.
This is what the manual for str_replace() says:
If you don't need fancy replacing rules (like regular expressions),
you should always use this function instead of preg_replace().
I think you should get your desired content using:
preg_match('/\+\+modal\+\+([^\+]+)\+\+endmodal\+\+/', $string, $matches)
$matches[1] = '<p>Hello</p>
You're trying to re-invent the wheel here. You're trying to write a simple template system here, but there are dozens of templating tools for PHP that you could use, ranging from big and complex like Smarty and Twig to really simple ones that aren't much more than you're trying to write.
I haven't used them all, so rather than recommend one I'll point you to a list of template engines you could try. You'll probably find more with a quick bit of googling.
If you do insist on writing your own, it's important to consider security. If you're outputting anything that contains data entered by your users, you must make sure all your output is properly escaped and sanitised for display on a web page; there a numerous common hacks that can take advantage of an insecure templating system to completely compromise a site.
<?php
$string = '++modal++<p>Hello</p>++endmodal++';
$patterns = array();
$patterns[0] = "/\+\+modal\+\+/"; // put '\' just before +
$patterns[1] = "/\+\+endmodal\+\+/";
$replacements = array();
$replacements[1] = '<html>';
$replacements[0] = '</html>';
echo preg_replace($patterns, $replacements, $string);
?>
Very similar to this example

PHP Regex for information between h4 tags

I am trying to grab what is the h4 text
$regex = '/<h4>([A-Za-z0-9\,\.])/';
I am just getting the first letter back, I cannot figure out how to use * to keep grabbing everything to the first < character.
I have made countless attempts and know I am overlooking something simple.
So I was making that much harder than I needed to, the following works:
$regex = '/<h4>.*?<\/h4>/';
If you can trust that grabbing all characters up to the first < is a good enough rule then use this:
$regex = '/<h4>([^<]*?)</';
Of course that definition will only grab 'The ' from <h4>The <b>Best</b> Book</h4> You can fix that be changing it to:
$regex = '/<h4>(.*?)<\/h4>/';
Which will grab everything between a <h4> and a </h4>, but still isn't perfect because anything like <h4 > or <h4 style="..."> will break it, along with a million other valid HTML examples. If you know that the contents won't have any < though, and you know your tag will always be exactly <h4> the first one works well enough for your situation.
If your situation is more complex you will want to use something like PHP's DOM extension (DOMDocument) which is meant for parsing HTML and XML, since neither are regular languages and cannot be parsed error free with regex.
You can use the below function to accomplish this task.
**function getTextBetweenTags($string, $tagname) {
$pattern = "/<$tagname ?.*>(.*)<\/$tagname>/";
preg_match($pattern, $string, $matches);
return $matches;
}**
In the first parameter you have to pass the complete string, and in the second parameter you have to pass the tagname ("h4")..

Categories