preg_replace and an array not working - php

This doesn't work. I expect it to replace each coinsurance of the array values with ralph. Instead, I get the unchanged value of $data back. Any insight as to why?
$data="there is a dog in the car out back";
$bill= explode(' ',$data);
$bob[0]="dog";
$bob[1]="car";
$bob[2]="back";
$qq = preg_replace("|($bob)|Ui", "ralph" , htmlspecialchars($data));
echo $qq;

If you interpolate an array like $bob in string context "$bob" then it just becomes "Array".
At the very least you would need to implode it again as alternatives list:
$regex_bob = implode("|", $bob); // you should also apply preg_quote()
# $regex_bob = "dog|car|back|...";
And then use a more sensible regex delimiter (as | is used for the alternatives):
$qq = preg_replace("~($regex_bob)~Ui", "ralph" , htmlspecialchars($data));

Just try this:
echo "|($bob)|Ui";
...and you will see what the problem is. If you just place an array into a string, it results in the string Array being added to the string - so the actual regex you are executing is:
"|(Array)|Ui"
You need to explicitly tell PHP how to convert the array to a string - in this case, I suggest you use implode():
$expr = "/(".implode('|',$bob).")/Ui";
$qq = preg_replace($expr, "ralph" , htmlspecialchars($data));
// Should return "there is a ralph in the ralph out ralph"
Note that I have also changed the delimiter to / - this is because you need to use | literally in the regex, so it is best to pick another delimiter.

Use it this way:
$data="there is a dog in the car out back";
$bill= explode(' ',$data);
$bob[0]="/dog/ui";
$bob[1]="/car/ui";
$bob[2]="/back/ui";
echo preg_replace($bob, "ralph", $data);
You have to pass a list of regular expressions, which you want to replace with a string or a list of replacements. More information: http://php.net/manual/en/function.preg-replace.php

Related

Replace random values with specific values in order in a string in PHP

Let's say I have a the following string:
{{Hi}}, This {{is}} {{Debby}}.
I want to replace the text inside {{ANYTHING}} with variables passed to a function. For example, if the function is change_values('Hola', 'was', 'Antonio').
The result would be:
Hola, This was Antonio.
First word or character surrounded by {{}} was replaced by the first parameter of change_values(). Similarly, the second word or character was replaced by the second parameter and so on.
To be clear, the values Hi, is and Debby can change. The passed parameters can also change. The only thing that is consistent is that First {{}} would be replaced by first parameter and so on.
I was planning on using str_replace() originally but the text keepschanging each time. I also thought about using regex but cannot figure out how to do the replacements sequentially.
Any help would be appreciated.
A few more examples,
{{Fiona}} is a lucky {{girl}}.
will become
Mike is a lucky man.
I am using {{}} as identifiers in the original string to make it easy to figure out what needs to be replaced. If this can create an issue, I am open to other (better) solutions.
If you're using PHP5.6 or later, this function will do what you want. It uses ... to pack all the replacements into an array, and then preg_replace to replace all the strings surrounded by {{ and }} with the replacements. By using the limit parameter to preg_replace, we prevent the pattern replacing all the {{}} strings with the first value in the replacements array.
function change_values($string, ...$replacements) {
return preg_replace(array_fill(0, count($replacements), '/{{[^}]+}}/'), $replacements, $string, 1);
}
echo change_values('{{Hi}}, This {{is}} {{Debby}}.', 'Hola', 'was', 'Antonio');
echo change_values('{{Fiona}} is a lucky {{girl}}.', 'Mike', 'man');
Output:
Hola, This was Antonio.
Mike is a lucky man.
$input = '{{Fiona}} is a lucky {{girl}}.';
$replaceArray = ['Mike', 'man'];
$expectedOut = 'Mike is a lucky man.';
preg_match_all('/({{\w+}})/', $input,$matches);
$out = str_replace($matches[0], $replaceArray, $input);
if($out === $expectedOut){
print_r($out);
}

Get data out of string

I am going to parse a log file and I wonder how I can convert such a string:
[5189192e][game]: kill killer='0:Tee' victim='1:nameless tee' weapon=5 special=0
into some kind of array:
$log['5189192e']['game']['killer'] = '0:Tee';
$log['5189192e']['game']['victim'] = '1:nameless tee';
$log['5189192e']['game']['weapon'] = '5';
$log['5189192e']['game']['special'] = '0';
The best way is to use function preg_match_all() and regular expressions.
For example to get 5189192e you need to use expression
/[0-9]{7}e/
This says that the first 7 characters are digits last character is e you can change it to fits any letter
/[0-9]{7}[a-z]+/
it is almost the same but fits every letter in the end
more advanced example with subpatterns and whole details
<?php
$matches = array();
preg_match_all('\[[0-9]{7}e\]\[game]: kill killer=\'([0-9]+):([a-zA-z]+)\' victim=\'([0-9]+):([a-zA-Z ]+)\' weapon=([0-9]+) special=([0-9])+\', $str, $matches);
print_r($matches);
?>
$str is string to be parsed
$matches contains the whole data you needed to be pared like killer id, weapon, name etc.
Using the function preg_match_all() and a regex you will be able to generate an array, which you then just have to organize into your multi-dimensional array:
here's the code:
$log_string = "[5189192e][game]: kill killer='0:Tee' victim='1:nameless tee' weapon=5 special=0";
preg_match_all("/^\[([0-9a-z]*)\]\[([a-z]*)\]: kill (.*)='(.*)' (.*)='(.*)' (.*)=([0-9]*) (.*)=([0-9]*)$/", $log_string, $result);
$log[$result[1][0]][$result[2][0]][$result[3][0]] = $result[4][0];
$log[$result[1][0]][$result[2][0]][$result[5][0]] = $result[6][0];
$log[$result[1][0]][$result[2][0]][$result[7][0]] = $result[8][0];
$log[$result[1][0]][$result[2][0]][$result[9][0]] = $result[10][0];
// $log is your formatted array
You definitely need a regex. Here is the pertaining PHP function and here is a regex syntax reference.

I need to get a value in PHP "preg_match_all" - Basic (I think)

I am trying to use a License PHP System…
I will like to show the status of their license to the users.
The license Server gives me this:
name=Service_Name;nextduedate=2013-02-25;status=Active
I need to have separated the data like this:
$name = “Service_Name”;
$nextduedate = “2013-02-25”;
$status = “Active”;
I have 2 days tring to resolve this problem with preg_match_all but i cant :(
This is basically a query string if you replace ; with &. You can try parse_str() like this:
$string = 'name=Service_Name;nextduedate=2013-02-25;status=Active';
parse_str(str_replace(';', '&', $string));
echo $name; // Service_Name
echo $nextduedate; // 2013-02-25
echo $status; // Active
This can rather simply be solved without regex. The use of explode() will help you.
$str = "name=Service_Name;nextduedate=2013-02-25;status=Active";
$split = explode(";", $str);
$structure = array();
foreach ($split as $element) {
$element = explode("=", $element);
$$element[0] = $element[1];
}
var_dump($name);
Though I urge you to use an array instead. Far more readable than inventing variables that didn't exist and are not explicitly declared.
It sounds like you just want to break the text down into separate lines along the semicolons, add a dollar sign at the front and then add spaces and quotes. I'm not sure you can do that in one step with a regular expression (or at least I don't want to think about what that regular expression would look like), but you can do it over multiple steps.
Use preg_split() to split the string into an array along the
semicolons.
Loop over the array.
Use str_replace to replace each '=' with ' = "'.
Use string concatenation to add a $ to the front and a "; to the end of each string.
That should work, assuming your data doesn't include quotes, equal signs, semicolons, etc. within the data. If it does, you'll have to figure out the parsing rules for that.

PHP : Get a number between 2 strings

I have this string:
a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}
I want to get number between "a:" and ":{" that is "3".
I try to user substr and strpos but no success.
I'm newbie in regex , write this :
preg_match('/a:(.+?):{/', $v);
But its return me 1.
Thanks for any tips.
preg_match returns the number of matches, in your case 1 match.
To get the matches themselves, use the third parameter:
$matches = array();
preg_match(/'a:(\d+?):{/', $v, $matches);
That said, I think the string looks like a serialized array which you could deserialize with unserialize and then use count on the actual array (i.e. $a = count(unserialize($v));). Be careful with userprovided serialized strings though …
If you know that a: is always at the beginning of the string, the easiest way is:
$array = explode( ':', $string, 3 );
$number = $array[1];
You can use sscanfDocs to obtain the number from the string:
# Input:
$str = 'a:3:{i:0;i:2;i:1;i:3;i:2;i:4;}';
# Code:
sscanf($str, 'a:%d:', $number);
# Output:
echo $number; # 3
This is often more simple than using preg_match when you'd like to obtain a specific value from a string that follows a pattern.
preg_match() returns the number of times it finds a match, that's why. you need to add a third param. $matches in which it will store the matches.
You were not too far away with strpos() and substr()
$pos_start = strpos($str,'a:')+2;
$pos_end = strpos($str,':{')-2;
$result = substr($str,$pos_start,$pos_end);
preg_match only checks for appearance, it doesn't return any string.

Using preg_replace to back reference array key and replace with a value

I have a string like this:
http://mysite.com/script.php?fruit=apple
And I have an associative array like this:
$fruitArray["apple"] = "green";
$fruitArray ["banana"] = "yellow";
I am trying to use preg_replace on the string, using the key in the array to back reference apple and replace it with green, like this:
$string = preg_replace('|http://mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|', 'http://mysite.com/'.$fruitArray[$1].'/', $string);
The process should return
http://mysite.com/green/
Obviously this isn’t working for me; how can I manipulate $fruitArray[$1] in the preg_replace statement so that the PHP is recognised, back referenced, and replaced with green?
Thanks!
You need to use the /e eval flag, or if you can spare a few lines preg_replace_callback.
$string = preg_replace(
'|http://mysite.com/script.php\?fruit=([a-zA-Z0-9_-]*)|e',
' "http://mysite.com/" . $fruitArray["$1"] ',
$string
);
Notice how the whole URL concatenation expression is enclosed in single quotes. It will be interpreted as PHP expression later, the spaces will vanish and the static URL string will be concatenated with whatever is in the fruitArray.

Categories