PHP preg_match & preg_replace outputing wrong - php

<?php
$string = "[img image:left]1.jpg[/img]Example Text 1[img image:left]2.jpg[/img] Example Text 2";
preg_match("/\[img\s*[^>]+\s*\](.*?)\[\/\s*img\]/i", $string, $match);
$result = preg_replace("/\[img\s*[^>]+\s*\](.*?)\[\/\s*img\]/i", $match['1'], $string);
echo $result;
?>
When using this code it should output 1.jpg, Example Text 1, 2.jpg, Example Text 2.
But however it shows only 2.jpg, Example Text 2.
I dont know what i'm doing wrong.

There are two fundamental issues:
you don't need to use a preg_match() and a preg_replace(), you can just use preg_replace() and reference your capture groups in the substitution
it looks like you copy pasted some code from HTML regex, and have [^>]+ inside of your [img], which says 1+ non-> characters..it should really be [^\]]+, 1+ non-] characters
Final solution:
$string = "[img image:left]1.jpg[/img]Example Text 1[img image:left]2.jpg[/img] Example Text 2";
$string = preg_replace("/\[img\s*[^\]]+\s*\](.*?)\[\/\s*img\]/i", ' \1 ', $string);
Demo: RegEx and PHP

Related

Regular Expression That Contains At Least One Of Each

I'm trying to capitalize "words" that have at least one number, letter, and special character such as a period or dash.
Things like: 3370.01b, 6510.01.b, m-5510.30, and drm-2013-c-004914.
I don't want it to match things like: hello, sk8, and mixed-up
I'm trying to use lookaheads, as suggested, but I can't get it to match anything.
$output = preg_replace_callback('/\b(?=.*[0-9]+)(?=.*[a-z]+)(?=.*[\.-]+)\b/i', function($matches){return strtoupper($matches[0]);}, $input);
You can use this regex to match the strings you want,
(?=\S*[a-z])(?=\S*\d)[a-z\d]+(?:[.-][a-z\d]+)+
Explanation:
(?=\S*[a-z]) - This look ahead ensures that there is at least an alphabet character in the incoming word
(?=\S*\d) - This look ahead ensures that there is at least a digit in the incoming word
[a-z\d]+(?:[.-][a-z\d]+)+ - This part captures a word contain alphanumeric word containing at least one special character . or -
Online Demo
Here is the PHP code demo modifying your code,
$input = '3370.01b, 6510.01.b, m-5510.30, and drm-2013-c-004914 hello, sk8, and mixed-up';
$output = preg_replace_callback('/(?=\S*[a-z])(?=\S*\d)[a-z\d]+(?:[.-][a-z\d]+)+/i', function($matches){return strtoupper($matches[0]);}, $input);
echo $output;
Prints,
3370.01B, 6510.01.B, M-5510.30, and DRM-2013-C-004914 hello, sk8, and mixed-up
Regular expression:
https://regex101.com/r/sdmlL8/1
(?=.*\d)(.*)([-.])(.*)
PHP code:
https://ideone.com/qEBZQc
$input = '3370.01b';
$output = preg_replace_callback('/(?=.*\d)(.*)([-.])(.*)/i', function($matches){return strtoupper($matches[0]);}, $input);
I don't think you never captured anything to put into matches...
$input = '3370.01b foo';
$output = preg_replace_callback('/(?=.*[0-9])(?=.*[a-z])(\w+(?:[-.]\w+)+)/i', function($matches){return strtoupper($matches[0]);}, $input);
echo $output;
Output
3370.01B foo
Sandbox
https://regex101.com/r/syJWMN/1

Change ocurrence inside a string

I am needing to change occurrence of string or numbers in php. In this situation, I need to change this, if it happens:
[code:154545edppy]
// my code here
[/code]
to this
[code]
// my code here
[/code]
I need to verify if letters and strings appear inside de opening block code. I am trying to do this with str_replace, but it's not working.
my code now:
$text = "[code:54as] [/code]";
$text = str_replace("[code: {(\d)}{(\w)}]", "[code]", $text);
$text = str_replace("[/code: {(\d)}{(\w)}]", "[/code]", $text);
echo $text;
str_replace is static. Use preg_replace with a regex and you can accomplish your task.
Something like:
$text = "[code:54as] [/code]";
echo preg_replace('~(\[/?.*?):.*?\]~', '$1]', $text);
Should do it.
PHP Demo: https://eval.in/643544
Regex demo: https://regex101.com/r/mD1bM3/1
If you only want to replace numbers and letters after the : use a character class in place of the second .*?. [A-Za-z\d]*?.

Replace all the first character of words in a string using preg_replace()

I have a string as
This is a sample text. This text will be used as a dummy for "various" RegEx "operations" using PHP.
I want to select and replace all the first alphabet of each word (in the example : T,i,a,s,t,T,t,w,b,u,a,d,f,",R,",u,P). How do I do it?
I tried /\b.{1}\w+\b/. I read the expression as "select any character that has length of 1 followed by word of any length" but didn't work.
You may try this regex as well:
(?<=\s|^)([a-zA-Z"])
Demo
Your regex - /\b.{1}\w+\b/ - matches any string that is not enclosed in word characters, starts with any symbol that is in a position after a word boundary (thus, it can even be whitespace if there is a letter/digit/underscore in front of it), followed with 1 or more alphanumeric symbols (\w) up to the word boundary.
That \b. is the culprit here.
If you plan to match any non-whitespace preceded with a whitespace, you can just use
/(?<!\S)\S/
Or
/(?<=^|\s)\S/
See demo
Then, replace with any symbol you need.
You may try to use the following regex:
(.)[^\s]*\s?
Using the preg_match_all and implode the output result group 1
<?php
$string = 'This is a sample text. This text will be used as a dummy for'
. '"various" RegEx "operations" using PHP.';
$pattern = '/(.)[^\s]*\s?/';
$matches;
preg_match_all($pattern, $string, $matches);
$output = implode('', $matches[1]);
echo $output; //Output is TiastTtwbuaadf"R"uP
For replace use something like preg_replace_callback like:
$pattern = '/(.)([^\s]*\s?)/';
$output2 = preg_replace_callback($pattern,
function($match) { return '_' . $match[2]; }, $string);
//result: _his _s _ _ample _ext. _his _ext _ill _e _sed _s _ _ummy _or _various" _egEx _operations" _sing _HP.

Make user name bolded in text in PHP

$text = 'Hello #demo here!';
$pattern = '/#(.*?)[ ]/';
$replacement = '<strong>${1}</strong> ';
echo preg_replace($pattern, $replacement, $text);
This works, I get HTML like this: Hello <strong>demo</strong> here!. But this not works, when that #demo is at the end of string, example: $text = 'Hello #demo';. How can I change my pattern, so it will return same output whenever it is end of the string or not.
Question 2:
What if the string is like $text = 'Hello #demo!';, so it will not put ! as bolded text? Just catch space, end of string or not real-word.
Sorry for bad English, hope you know what I need.
In order to select a word beginning with the # symbol, this regex will work:
$pattern = "/#(\w+)\b/"
`\w` is a short hand character class for `[a-zA-Z0-9_]`. `\b` is an anchor for the beginning or end of a word, in this case the end. So the regex is saying: select something starting with an '#' followed by one or more word characters until the end of the word is reached.
Reference: http://www.regular-expressions.info/tutorial.
You could use a word boundary, that's what they're for:
$pattern = '/#(.+?)\b/';
This will work for question 2 also
You can add an option to match the end of the string:
#(.*?)(?= |\p{P}?$)
Replace with <strong>$1</strong>.
You can also use \p{P} (any Unicode punctuation symbol) to prevent punctuation from bold formatting.
Here is a demo.

Converting Npx to [N/10]rem with regex

I have php code that writes a string, which is actually an html file, to the server, but before the write I want to rip through and replace all "Npx" with "[N/10]rem". So "width:203px" would become "width:20.3rem" and top:46px" would become "top:4.6rem". Does anyone see a regex string that will do this?
Thanks
Just capture the digit before px then match the string px and replace all the chars with .$1rem
. Where $1 refers to the characters which are present inside the group index 1.
(\d)px
Replacement string:
.$1rem
DEMO
$string = <<<EOT
width:203px
top:46px
top:6px
EOT;
$pattern = "~(\d)px~";
$replacement = ".$1rem";
echo preg_replace($pattern, $replacement, $string);
Output:
width:20.3rem
top:4.6rem
top:.6rem

Categories