Replacing items in an array using two regular expressions - php

Can you use two regex in preg_replace to match and replace items in an array?
So for example:
Assume you have:
Array
(
[0] => mailto:9bc0d67a-0#acoregroup.com
[1] => mailto:347c6b#acoregroup.com
[2] => mailto:3b3cce0a-0#acoregroup.com
[3] => mailto:9b690cc#acoregroup.com
[4] => mailto:3b7f59c1-4bc#acoregroup.com
[5] => mailto:cc62c936-7d#acoregroup.com
[6] => mailto:5270f9#acoregroup.com
}
and you have two variables holding regex strings:
$reg = '/mailto:[\w-]+#([\w-]+\.)+[\w-]+/i';
$replace = '/[\w-]+#([\w-]+\.)+[\w-]+/i';
can I:
preg_replace($reg,$replace,$matches);
In order to replace "mailto:9bc0d67a-0#acoregroup.com" with "9bc0d67a-0#acoregroup.com" in each index of the array.

You could try this:
$newArray = preg_replace('/mailto:([\w-]+#([\w-]+\.)+[\w-]+)/i', '$1', $oldArray);
Haven't tested
See here: http://php.net/manual/en/function.preg-replace.php

foreach($array as $ind => $value)
$array[$ind] = preg_replace('/mailto:([\w-]+#([\w-]+\.)+[\w-]+)/i', '$1', $value);
EDIT: gahooa's solution is probably better, because it moves the loop inside preg_replace.

For this type of substitution you should use str_replace it is mutch faster and strongly suggested by the online documentation:
$array = str_replace('mailto:', '', $array);

I think that you are looking for the '$1' submatch groups, as others have already pointed out. But why can't you just do the following:
// strip 'mailto:' from the start of each array entry
$newArray = preg_replace('/^mailto:\s*/i', '', $array);
In fact, seeing as your regex doesn't allow the use of ':' anywhere in the email addresses, you could do it with a simple str_replace():
// remove 'mailto:' from each item
$newArray = str_replace('mailto:', '', $array);

Related

Facing issue with parse_str(), Replacing + char to space

I have the following string url:
HostName=MyHostName;SharedAccessKeyName=SOMETHING;SharedAccessKey=VALUE+VALUE=
I need to extract the key-value pair in an array. I have used parse_str() in PHP below is my code:
<?php
$arr = array();
$str = "HostName=MyHostName&SharedAccessKeyName=SOMETHING&SharedAccessKey=VALUE+VALUE=";
parse_str($str,$arr);
var_dump($arr);
output:
array (
'HostName' => 'MyHostName',
'SharedAccessKeyName' => 'SOMETHING',
'SharedAccessKey' => 'VALUE VALUE=',
)
you can see in the SharedAccessKey char + is replaced by space for this issue, I referred the Similiar Question, Marked answer is not the correct one according to the OP scenario, This says that first do urlencode() and then pass it because parse_str() first decode URL then separate the key-values but this will return array object of a single array which return the whole string as it is like for my case its output is like:
Array
(
[HostName=MyHostName&SharedAccessKeyName=SOMETHING&SharedAccessKey=VALUE+VALUE=] =>
)
Please help me out, not for only + char rather for all the characters should come same as they by the parse_str()
You could try emulating parse_str with preg_match_all:
preg_match_all('/(?:^|\G)(\w+)=([^&]+)(?:&|$)/', $str, $matches);
print_r(array_combine($matches[1], $matches[2]));
Output:
Array (
[HostName] => MyHostName
[SharedAccessKeyName] => SOMETHING
[SharedAccessKey] => VALUE+VALUE=
)
Demo on 3v4l.org
$str = "HostName=MyHostName&SharedAccessKeyName=SOMETHING&SharedAccessKey=VALUE+VALUE=";
preg_match_all('/(?:^|G)(w+)=([^&]+)(?:&|$)/', $str, $matches);
print_r(array_combine($matches[1], $matches[2]));

How to extract substrings with delimiters from a string in php

I would like to remove substrings from a string that have delimiters.
Example:
$string = "Hi, I want to buy an [apple] and a [banana].";
How do I get "apple" and "banana" out of this string and in an array? And the other parts of the string "Hi, I want to buy an" and "and a" in another array.
I apologize if this question has already been answered. I searched this site and couldn't find anything that would help me. Every situation was just a little different.
You could use preg_split() thus:
<?php
$pattern = '/[\[\]]/'; // Split on either [ or ]
$string = "Hi, I want to buy an [apple] and a [banana].";
echo print_r(preg_split($pattern, $string), true);
which outputs:
Array
(
[0] => Hi, I want to buy an
[1] => apple
[2] => and a
[3] => banana
[4] => .
)
You can trim the whitespace if you like and/or ignore the final fullstop.
preg_match_all('(?<=\[)([a-z])*(?=\])', $string, $matches);
Should do what you want. $matches will be an array with each match.
I assume you want words as values in the array:
$words = explode(' ', $string);
$result = preg_grep('/\[[^\]]+\]/', $words);
$others = array_diff($words, $result);
Create an array of words using explode() on a space
Use a regex to find [somethings] using preg_grep()
Find the difference of all words and [somethings] using array_diff(), which will be the "other" parts of the string

How to form two arrays from string separated by "," and followed by -?

$str="a,b,c,d-e,f,g,h"
I am trying to extract the strings from $str that are separated "," and are before "-" in one array and the strings separated by "," and are after "-" in second array. So that $arr1=array(a,b,c,d); and $arr2=array(e,f,g,h);. I am just using $str as an example and generally I want this to work for any string of the same form i.e. $str=s1,s2,s3,s4,s5,....-r1,r2,t3....
NOTE: If $str doesn't have "-" then $arr2 vanishes and $arr1 contains an array of the elements separated by ',' in $str.
This is what I tried
preg_match_all('~(^|.*,)(.*)(,.*|\-|$)~', $str, $arr1);
preg_match_all('~(-|.*,)(.*)(,.*|$)~', $str, $arr2);
However each array comes with one element that contains the string str.
Does anyone know why this is not working.
All of your regex patterns are not optimal and it seems the task is easier to solve with explode and array_map:
array_map() returns an array containing all the elements of array1 after applying the callback function to each one. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map()
$str="a,b,c,d-e,f,g,h";
$ex = array_map(function ($s) {
return explode(",", $s);
}, explode("-", $str));
print_r($ex);
See IDEONE demo
Results:
Array
(
[0] => Array
(
[0] => a
[1] => b
[2] => c
[3] => d
)
[1] => Array
(
[0] => e
[1] => f
[2] => g
[3] => h
)
)
^(.*?(?=-|$))|(?<=-)(.*$)
You can use this to get 2 arrays.See demo.
https://regex101.com/r/vV1wW6/19
Your regex is not working as you have used greedy modifier..*, will stop at the last instance of ,
EDIT:
Use this is you want string after - to be in second group.
^(.*?(?=-|$))(?:-(.*$))?
https://regex101.com/r/vV1wW6/20
You can simply use preg_match to check does your string contains - if yes than can simply use array_walk like as
$str = 'a,b,c,d-e,f,g,h';
$result = [];
if(preg_match('/[-]/', $str)){
array_walk(explode('-',$str),function($v,$k)use(&$result){
$result[] = explode(',',$v);
});
}else{
array_walk(explode(',',$str),function($v,$k)use(&$result){
$result[] = $v;
});
}
print_r($result);
Without regex (the most reasonable way):
$str="a,b,c,d-e,f,g,h";
list($arr1, $arr2) = explode('-', $str);
$arr1 = explode(',', $arr1);
if ($arr2)
$arr2 = explode(',', $arr2);
else
unset($arr2);
With regex (for the challenge):
if (preg_match_all('~(?:(?!\G)|\A)([^-,]+)|-?([^,]+),?~', $str, $m)) {
$arr1 = array_filter($m[1]);
if (!$arr2 = array_filter($m[2]))
unset($arr2);
}

Remove elements from an array that do not match a regex

In PHP, is there a function or anything else that will remove all elements in an array that do not match a regex.
My regex is this: preg_match('/^[a-z0-9\-]+$/i', $str)
My array's come in like this, from a form (they're tags actually)
Original array from form. Note: evil tags
$arr = array (
"french-cuisine",
"french-fries",
"snack-food",
"evil*tag!!",
"fast-food",
"more~evil*tags"
);
Cleaned array. Note, no evil tags
Array (
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[3] => fast-food
)
I currently do like this, but is there a better way? Without the loop maybe?
foreach($arr as $key => $value) {
if(!preg_match('/^[a-z0-9\-]+$/i', $value)) {
unset($arr[$key]);
}
}
print_r($arr);
You could use preg_grep() to filter the array entries that match the regular expression.
$cleaned = preg_grep('/^[a-z0-9-]+$/i', $arr);
print_r($cleaned);
Output
Array
(
[0] => french-cuisine
[1] => french-fries
[2] => snack-food
[4] => fast-food
)
I would not necessarily say it's any better per se, but using regexp and array_filter could look something like this:
$data = array_filter($arr , function ($item){
return preg_match('/^[a-z0-9\-]+$/i', $item);
});
Where we're returning the result of the preg_match which is either true/false. In this case, it should correctly remove the matched evil tags.
Here's your eval.in

How do I return words from strings using regular expressions?

I have some data which looks like:
{i:0;s:2:"69";i:1;s:2:"70";i:2;s:2:"71";i:3;s:2:"72";i:4;s:2:"73";i:5;s:2:"74";i:6;s:2:"75";i:7;s:2:"76";i:8;s:2:"77";}
I need to remove all items within quotation marks, e.g. 69,70,..,77.
I understand I should use the preg_split function.
I'm looking for help regarding the regular expression I need to pass to preg_split in order to return the required data.
Edit
Sorry, my initial question wasn't clear. I want to gather all values between speech marks and have them returned in an array (i'm not interested in keeping the rest of the data - all I require are the values within speech marks)
Edit 2
The data is a serialized object, I didn't include the full object in order to save space.
without regexp:
$v = 'a:9:{i:0;s:2:"69";i:1;s:2:"70";i:2;s:2:"71";i:3;s:2:"72";i:4;s:2:"73";i:5;s:2:"74";i:6;s:2:"75";i:7;s:2:"76";i:8;s:2:"77";}';
$v = unserialize($v);
print_r($v);
$v = array_combine(array_keys($v), array_fill(0, count($v), ''));
echo serialize($v);
but this looks, how max mentioned, like a (part of a) serialized object.
you should check if you are able to work with the complete syntax of it...
update
well, if you only want the values of this serialized array, it gets even easier:
$v = 'a:9:{i:0;s:2:"69";i:1;s:2:"70";i:2;s:2:"71";i:3;s:2:"72";i:4;s:2:"73";i:5;s:2:"74";i:6;s:2:"75";i:7;s:2:"76";i:8;s:2:"77";}';
$v = unserialize($v);
$v = array_values($v);
print_r($v);
output:
Array
(
[0] => 69
[1] => 70
[2] => 71
[3] => 72
[4] => 73
[5] => 74
[6] => 75
[7] => 76
[8] => 77
)
array_values() isn't even necessary, really.
If you really want to delete all numbers between quotation marks, just use
$string = preg_replace('/"[0-9]+"/', '""', $string);
If you want to delete everything between these, use
$string = preg_replace('/"[^"]+"/', '""', $string);
To your edited question:
preg_match_all('/"([^"]+)"/', $string, $matches);
$matches will contain an array of arrays containing the strings.
Something like this should work:
$str = '{i:0;s:2:"69";i:1;s:2:"70";i:2;s:2:"71";i:3;s:2:"72";i:4;s:2:"73";i:5;s:2:"74";i:6;s:2:"75";i:7;s:2:"76";i:8;s:2:"77";}';
$str = preg_replace('#:"[^"]*"#', '', $str);
echo $str . "\n";
This will be more useful
$data = 'a:9:{i:0;s:2:"69";i:1;s:2:"70";i:2;s:2:"71";i:3;s:2:"72";i:4;s:2:"73";i:5;s:2:"74";i:6;s:2:"75";i:7;s:2:"76";i:8;s:2:"77";}';
$data = unserialize($data);
echo implode(',',$data);

Categories