preg replace string containing square brackets - php

I have a string like this: [name-123456].
I am attempting to replace the match of this string with some predefined strings. Here is what I have so far:
preg_replace('~\['.$string_to_be_replaced.'\]~', $code_to_replace_it_with, $content);
Currently this throws an error, I couldn't find out how to remove the square brackets (even though they are part of the string). How do I make sure those get removed in a regex so that [name-123456] gets replaced with stringofcode?
EDIT:
$string_to_be_replaced = preg_quote($string_to_be_replaced, "~");
$content = preg_replace('~\['.$string_to_be_replaced.'\]~', $str_to_replace_with, $content);
this simply returns [name-123456] :p
A vardump produces: string(16) "\[name\-123456\]"

Your first problem is likely that you didn't assign the result back:
$content = preg_replace('~...~', $rpl.., $content);
Then you should also escape the $string_to_be_replaced using preg_quote beforehand. It's necessary for the - in your search string anyway.
$string_to_be_replaced = preg_quote($string_to_be_replaced, "~");
Would also take care of the [ square ] brackets, btw.
And if you're not doing any assertions or complex matching, str_replace() might be an alternative.

Related

Use regex to quote the name in name-value pair of a list of pairs

I am trying to put quotes around the names of name-value pairs separated by commas. I use preg_replace and regex to achieve that. However, my pattern is not working properly.
$str="f1=1,f2='2',f3='a',f4=4,f5='5'";
$newstr=Preg_replace(/'(?.[^=]+)'/,"'$1'",$str);
I expected $newstr to come out like so:
'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5'
But it doesn't and the qoutes don't contain the name.
What should the pattern be and how can I use the comma to get all of them correctly?
There are a few issues with your attempt:
PHP does not have a regex-literal syntax as in JavaScript, so starting the regex value with a forward slash is a syntax error. It should be a string, so start with a quote. Maybe you accidently swapped the slash and quote at the start and the end.
(?. is not valid. Maybe you intended (?:, but then there is no capture group and $1 is not a valid back reference. To have the capture group, you should not have (?., but just (.
[^=]+ could include substrings like 1,f2. There should be logic to not start matching while still inside a value (whether quoted or not).
I would suggest a regex where you match both parts around the = (both key and value), and then in the replacement, just reproduce the second part without change. This will ensure you don't accidently use anything in the value side for wrapping in quotes:
$newstr = preg_replace("/([^,=]+)=('[^']*'|[^,]*)/","'$1'=$2",$str);
Basically, match beginning of line or a comma (with negative capture) and then capture everything until a =
$reg = "/(?<=^|,)([^=]+)/";
$str = "f1=1,f2='2',f3='a',f4=4,f5='5'";
print_r(preg_replace($reg, "'$1'", $str));
// output:
// 'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5'
This will also work, a different approach, but assuming there will be no comma in the values or names except the separators..
$newstr = preg_replace("/(.)(?==)|(?<=,|^)(.)/", "$1'$2", $str);
But I believe string and simple array operations will be faster as the regex is really getting complex and there are so many steps to get the characters.. Here is the same output but with array functions only.
$newstr = implode(",", array_map(function($element){ return "'". implode("'=", explode("=", $element)); }, explode(",", $str)));
RegEx is not always fast than string or array operations, but yes it can do complex things with little bit of code.

PHP escaping delimiter

I am using PHPs' strtr method to replace certain tokens/placeholders in a string. This works very well but now I'm trying to work out if all of my tokens were replaced.
The following example:
$trans = array(":hello" => "hi", ":hi" => "hello");
echo strtr(":hi all, I said :hello", $trans);
will output:
hello all, I said hi
Both tokens were replaced successfully but how do I check this. I can't search the output for occurrences of my delimiter ':' since the output string could contain valid ':' in the data.
Is there a way that I can escape these delimiters before doing the replace, then do a count on the unescaped delimiters to see if there were any token left unreplaced, and then finally unescape the escaped delimiters before returning?
NOTE: I cannot use str_replace, this method needs to be used.
I don't think strtr can help you here, it just replaces whatever it finds. What you seem to want is to figure out if there is a difference between the tokens in the array and in the string. For that, something like this should do:
preg_match_all('/:\w+/', $str, $matches);
if (array_diff($matches[0], array_keys($trans))) {
// the string has tokens that aren't in $trans
}

PHP Preg_replace: can't get the replace part to work, finding is fine

I don't know how to do the following:
find all instances of '/\s[2-9]\)/' and replace the space with a <br /> tag.
Something as simple as this doesn't work:
$preg_num = ' /\s[2-9]\)/';
$preg_fix = "'/<br>/[2-9]\)'";
preg_replace($preg_num,$preg_fix,$notes);
What do I need to change the $preg_fix variable to?
Using a lookahead is simpler than a backreference, IMHO.
$preg_num = '/\s(?=[2-9]\))/';
$preg_fix = '<br/>';
preg_replace($preg_num,$preg_fix,$notes);
This way, you are only replacing the space with the <br/>.
The replacement string is not treated as a regex — it is more like a literal string. If you are trying to put whatever digit [2-9] that was matched in the original regex into the replacement string, capture the character as a group and use a backreference.
$preg_num = '/\s([2-9])\)/';
$preg_fix = "<br />$1)'";
preg_replace($preg_num,$preg_fix,$notes);
For more information:
preg_replace's replacement parameter documentation
Regular expression grouping: "Use Round Brackets for Grouping"

PHP / Regex : match json inside json

Just a quick regex question...hopefully
I have a string that looks something like this:
$string = 'some text [ something {"index":"{"index2":"value2"}"}] [something2 {"here to be":"more specific"}]';
I want to be able to get the value:
{"index":"{"index2":"value2"}"}
But all my attempts at matching (or replacing) keep giving me:
{"index":"{"index2":"value2"}
preg_replace('/\[(.*?)({.*?[^}]})*?\]/is', "", $string);
Here I'm matching the whole square bracket area, but hopefully you can see what I'm trying to do.
The negation of the "do not match }" doesn't seem to be doing anything. Maybe I just need an OR in there or something.
Well, thanks if you have time to answer.
The $string could contain multiple instances of the {} so a greedy regex won't work....that I know of.
You can't make a regex count the opening brackets and the corresponding closeing brackets, you should use a simple for loop to do that, but you can get the complete string from the first opening bracket to the last closeing one with a greedy expression like: ({.*}). Note that simple string functions are much faster then regular expressions, so you should use those instead.

PHP: regular expression to remove bracket codes

I am trying to make a function to remove all the bracket codes but it doesn't seem to be working,
function anti_code($content)
{
# find the matches and then remove them
$output = preg_replace("/\[a-z\s+\]/is", "", $content);
# return the result
return $output;
}
I want these codes to be removed in the output,
Agro[space]terrorism
Agro[en space]terrorism
so that I can get
Agroterrorism
I must be something wrong in my regular expression! Please let me know. Thanks.
You escaped the [], but didn't add a second set of unescaped [] to designate a character class. Also, the s is not necessary if you're not using the . metacharacter in your regex.
Try this:
/\[[a-z\s]+\]/i
If you don't care what's between the square brackets and just want to remove everything contained in them, this will do:
/\[[^]]+\]/i
Try \[[a-z\s]+\] It will capture brackets and all contents

Categories