php replace all occurances of key from array in string - php

maybe this is duplicate but i did't find good solution.
I have array
$list = Array
(
[hi] => 0
[man] => 1
);
$string="hi man, how are you? man is here. hi again."
It should produce $final_string = "0 1, how are you? 1 is here. 0 again."
How can I achieve it with smart way? Many thanks.

Off of the top of my head:
$find = array_keys($list);
$replace = array_values($list);
$new_string = str_ireplace($find, $replace, $string);

Can be done in one line using strtr().
Quoting the documentation:
If given two arguments, the second should be an array in the form array('from' => 'to', ...). The return value is a string where all the occurrences of the array keys have been replaced by the corresponding values. The longest keys will be tried first. Once a substring has been replaced, its new value will not be searched again.
To get the modified string, you'd just do:
$newString = strtr($string, $list);
This would output:
0 1, how are you? 1 is here. 0 again.
Demo.

$text = strtr($text, $array_from_to)
See http://php.net/manual/en/function.strtr.php

preg_replace may be helpful.
<?php
$list = Array
(
'hi' => 0,
'man' => 1
);
$string="hi man, how are you? Man is here. Hi again.";
$patterns = array();
$replacements = array();
foreach ($list as $k => $v)
{
$patterns[] = '/' . $k . '/i'; // use i to ignore case
$replacements[] = $v;
}
echo preg_replace($patterns, $replacements, $string);

Related

(PHP) Replace string of array elements using regex

I have an array
Array
(
[0] => "http://example1.com"
[1] => "http://example2.com"
[2] => "http://example3.com"
...
)
And I want to replace the http with https of each elements using RegEx. I tried:
$Regex = "/http/";
$str_rpl = '${1}s';
...
foreach ($url_array as $key => $value) {
$value = preg_replace($Regex, $str_rpl, $value);
}
print_r($url_array);
But the result array is still the same. Any thought?
You actually print an array without changing it. Why do you need regex for this?
Edited with Casimir et Hippolyte's hint:
This is a solution using regex:
$url_array = array
(
0 => "http://example1.com",
1 => "http://example2.com",
2 => "http://example3.com",
);
$url_array = preg_replace("/^http:/i", "https:", $url_array);
print_r($url_array);
PHP Demo
Without regex:
$url_array = array
(
0 => "http://example1.com",
1 => "http://example2.com",
2 => "http://example3.com",
);
$url_array = str_replace("http://", "https://", $url_array);
print_r($url_array);
PHP Demo
First of all, you are not modifying the array values at all. In your example, you are operating on the copies of array values. To actually modify array elements:
use reference mark
foreach($foo as $key => &$value) {
$value = 'new value';
}
or use for instead of foreach loop
for($i = 0; $i < count($foo); $i++) {
$foo[$i] = 'new value';
}
Going back to your question, you can also solve your problem without using regex (whenever you can, it is always better to not use regex [less problems, simpler debugging, testing etc.])
$tmp = array_map(static function(string $value) {
return str_replace('http://', 'https://', $value);
}, $url_array);
print_r($tmp);
EDIT:
As Casimir pointed out, since str_replace can take array as third argument, you can just do:
$tmp = str_replace('http://', 'https://', $url_array);
This expression might also work:
^http\K(?=:)
which we can add more boundaries, and for instance validate the URLs, if necessary, such as:
^http\K(?=:\/\/[a-z0-9_-]+\.[a-z0-9_-]+)
DEMO
Test
$re = '/^http\K(?=:\/\/[a-z0-9_-]+\.[a-z0-9_-]+)/si';
$str = ' http://example1.com ';
$subst = 's';
echo preg_replace($re, $subst, trim($str));
Output
https://example1.com
The expression is explained on the top right panel of regex101.com, if you wish to explore/simplify/modify it, and in this link, you can watch how it would match against some sample inputs, if you like.
RegEx Circuit
jex.im visualizes regular expressions:

PHP Regex for a specific numeric value inside a comma-delimited integer number string

I am trying to get the integer on the left and right for an input from the $str variable using REGEX. But I keep getting the commas back along with the integer. I only want integers not the commas. I have also tried replacing the wildcard . with \d but still no resolution.
$str = "1,2,3,4,5,6";
function pagination()
{
global $str;
// Using number 4 as an input from the string
preg_match('/(.{2})(4)(.{2})/', $str, $matches);
echo $matches[0]."\n".$matches[1]."\n".$matches[1]."\n".$matches[1]."\n";
}
pagination();
How about using a CSV parser?
$str = "1,2,3,4,5,6";
$line = str_getcsv($str);
$target = 4;
foreach($line as $key => $value) {
if($value == $target) {
echo $line[($key-1)] . '<--low high-->' . $line[($key+1)];
}
}
Output:
3<--low high-->5
or a regex could be
$str = "1,2,3,4,5,6";
preg_match('/(\d+),4,(\d+)/', $str, $matches);
echo $matches[1]."<--low high->".$matches[2];
Output:
3<--low high->5
The only flaw with these approaches is if the number is the start or end of range. Would that ever be the case?
I believe you're looking for Regex Non Capture Group
Here's what I did:
$regStr = "1,2,3,4,5,6";
$regex = "/(\d)(?:,)(4)(?:,)(\d)/";
preg_match($regex, $regStr, $results);
print_r($results);
Gives me the results:
Array ( [0] => 3,4,5 [1] => 3 [2] => 4 [3] => 5 )
Hope this helps!
Given your function name I am going to assume you need this for pagination.
The following solution might be easier:
$str = "1,2,3,4,5,6,7,8,9,10";
$str_parts = explode(',', $str);
// reset and end return the first and last element of an array respectively
$start = reset($str_parts);
$end = end($str_parts);
This prevents your regex from having to deal with your numbers getting into the double digits.

PHP - How can I find pull out only the integers in a string that separates the integers with two periods?

Say I have a string like this:
$string = '.30..5..12..184..6..18..201..1.'
How would I pull out each of the integers, stripping the periods, and store them into an array?
You could use this. You break the string up by all of the periods... but this only works if it is exactly like that; if there is other stuff in the middle for example 25.sdg.12 it wouldnt work.
<?php
$my_array = explode("..",$string);
$my_array[0] = trim($my_array[0]); //This removes the period in first part making '.30' into '30'
///XXX $my_array[-1] = trim($my_array[-1]); XXX If your string is always the same format as that you could just use 7 instead.
I checked and PHP doesn't support negative indexes but you can count the array list and just use that. Ex:
$my_index = count($my_array) - 1;
$my_array[$my_index] = trim($my_array[$my_index]); //That should replace '1.' with '1' no matter what format or length your string is.
?>
This will break up your string into an array and then loop through to grab numbers.
$string = '.30..5..12..184..6..18..201..1.';
$pieces = explode('.', $string);
foreach($pieces as $key=>$val) {
if( is_numeric($val) ) {
$numbers[] = $val;
}
}
Your numbers will be in the array $numbers
All I could think of.
<?php
$string = '.30..5..12..184..6..18..201..1.';
$r_string = str_replace("..", ",", $string);
$r_string = str_replace(".", ",", $r_string);
print_r(explode(",", $r_string));
?>
Or If you want to the array in a variable
<?php
$string = '.30..5..12..184..6..18..201..1.';
$r_string = str_replace("..", ",", $string);
$r_string = str_replace(".", ",", $r_string);
$arr_ex = explode(",", $r_string);
print_r($arr_ex);
?>
Someone else posted this but then removed their code, it works as intended:
<?php
$string = '.30..5..12..184..6..18..201..1.';
$numbers = array_filter (explode ('.', $string), 'is_numeric');
print_r ($numbers);
?>
Output:
Array (
[1] => 30
[3] => 5
[5] => 12
[7] => 184
[9] => 6
[11] => 18
[13] => 201
[15] => 1 )
try this ..
$string = '.30..5..12..184..6..18..201..1.';
$new_string =str_replace(".", "", str_replace("..", ",", $string));
print_r (explode(",",$new_string));
One line solution:
print_r(explode("..",substr($string,1,-1)));

php preg_match tab separated

I need a regular expression to look for the first N chars on an array until a tab or comma separation is found.
array look like:
array (
0 => '001,Foo,Bar',
1 => '0003,Foo,Bar',
2 => '3000,Foo,Bar',
3 => '3333433,Foo,Bar',
)
I'm looking for the first N chars, so for instance, pattern to search is 0003, get array index 1...
What would be a good way of doing this?
/^(.*?)[,\t]/
?
Try the regular expression /^0003,/ together with preg_grep:
$array = array('001,Foo,Bar', '0003,Foo,Bar', '3000,Foo,Bar', '3333433,Foo,Bar');
$matches = preg_grep('/^0003,/', $array);
var_dump($matches);
A REGEXP replacement would be: strpos() and substr()
Following your edit:
Use trim(), after searching for a comma with strpos() and retrieving the required string with substr().
use preg_split on the string
$length=10;
foreach($arr as $string) {
list($until_tab,$rest)=preg_split("/[\t,]+/", $string);
$match=substr($until_tab, $length);
echo $match;
}
or
array_walk($arr, create_function('&$v', 'list($v,$rest) = preg_split("/[\t,]+/", $string);'); //syntax not checked
This PHP5 code will do a prefix search on the first element, expecting a trailing comma. It's O(n), linear, inefficient, slow, etc. You'll need a better data structure if you want better search speed.
<?php
function searchPrefix(array $a, $needle) {
$expression = '/^' . quotemeta($needle) . ',/';
$results = array();
foreach ($a as $k => $v)
if (preg_match($expression, $v)) $results[] = $k;
return $results;
}
print_r(searchPrefix($a, '0003'));
$pattern = '/^[0-9]/siU';
for($i=0;$i<count($yourarray);$i++)
{
$ids = $yourarray[$i];
if(preg_match($pattern,$ids))
{
$results[$i] = $yourarray[$i];
}
}
print_r($results);
this will print
0 => '001',
1 => '0003',
2 => '3000',
3 => '3333433'

PHP str_replace

I'm currently using str_replace to remove a usrID and the 'comma' immediately after it:
For example:
$usrID = 23;
$string = "22,23,24,25";
$receivers = str_replace($usrID.",", '', $string); //Would output: "22,24,25"
However, I've noticed that if:
$usrID = 25; //or the Last Number in the $string
It does not work, because there is not a trailing 'comma' after the '25'
Is there a better way I can be removing a specific number from the string?
Thanks.
YOu could explode the string into an array :
$list = explode(',', $string);
var_dump($list);
Which will give you :
array
0 => string '22' (length=2)
1 => string '23' (length=2)
2 => string '24' (length=2)
3 => string '25' (length=2)
Then, do whatever you want on that array ; like remove the entry you don't want anymore :
foreach ($list as $key => $value) {
if ($value == $usrID) {
unset($list[$key]);
}
}
var_dump($list);
Which gives you :
array
0 => string '22' (length=2)
2 => string '24' (length=2)
3 => string '25' (length=2)
And, finally, put the pieces back together :
$new_string = implode(',', $list);
var_dump($new_string);
And you get what you wanted :
string '22,24,25' (length=8)
Maybe not as "simple" as a regex ; but the day you'll need to do more with your elements (or the day your elements are more complicated than just plain numbers), that'll still work :-)
EDIT : and if you want to remove "empty" values, like when there are two comma, you just have to modifiy the condition, a bit like this :
foreach ($list as $key => $value) {
if ($value == $usrID || trim($value)==='') {
unset($list[$key]);
}
}
ie, exclude the $values that are empty. The "trim" is used so $string = "22,23, ,24,25"; can also be dealt with, btw.
Another issue is if you have a user 5 and try to remove them, you'd turn 15 into 1, 25 into 2, etc. So you'd have to check for a comma on both sides.
If you want to have a delimited string like that, I'd put a comma on both ends of both the search and the list, though it'd be inefficient if it gets very long.
An example would be:
$receivers = substr(str_replace(','.$usrID.',', ',', ','.$string.','),1,-1);
An option similar to Pascal's, although I think a bit simipler:
$usrID = 23;
$string = "22,23,24,25";
$list = explode(',', $string);
$foundKey = array_search($usrID, $list);
if ($foundKey !== false) {
// the user id has been found, so remove it and implode the string
unset($list[$foundKey]);
$receivers = implode(',', $list);
} else {
// the user id was not found, so the original string is complete
$receivers = $string;
}
Basically, convert the string into an array, find the user ID, if it exists, unset it and then implode the array again.
I would go the simple way: add commas around your list, replace ",23," with a single comma then remove extra commas. Fast and simple.
$usrID = 23;
$string = "22,23,24,25";
$receivers = trim(str_replace(",$usrID,", ',', ",$string,"), ',');
With that said, manipulating values in a comma separated list is usually sign of a bad design. Those values should be in an array instead.
Try using preg:
<?php
$string = "22,23,24,25";
$usrID = '23';
$pattern = '/\b' . $usrID . '\b,?/i';
$replacement = '';
echo preg_replace($pattern, $replacement, $string);
?>
Update: changed $pattern = '/$usrID,?/i'; to $pattern = '/' . $usrID . ',?/i';
Update2: changed $pattern = '/' . $usrID . ',?/i to $pattern = '/\b' . $usrID . '\b,?/i' to address onnodb's comment...
Simple way (providing all 2 digit numbers):
$string = str_replace($userId, ',', $string);
$string = str_replace(',,','', $string);

Categories