I don't know what to call this definition problem. I need to parse value from preg_match_all. before i get the value i want. I need to parse again the multidimensional array value return by preg_match_all.
The point is I need to reuse code with different value. The different only in variable $regex and $match[1][0]; In my database I have 2 columns. Regex value is pattern regex to match. The second column is $match[1][0] variable. What is call the definition?
I don't want to pass value variable $match[1][0]. but the $match[1][0]. and use it later with loop.
<?php
$temporary = "$match[1][0]";
preg_match_all($regex, $source, $match);
$match = $temporary;
echo $match;
You can try eval() function。It run a string with php code!
You can like this
$match = [
1 => [
[1]
]
];
$temporary = '$match[1][0]';
$match = eval('return $match[1][0];');
var_dump($match);
Related
I have a problem. I don't know what could be the cause. What I want to do is to know if an element of an array has a certain word, and I use this regular expression /.*example.*/, and this is the code:
$array = ['example1', '2example', 'no'];
$matches = [];
$var = "example";
foreach($array as $element)
{
preg_match("/.*$var.*/", $element, $matches);
}
But when I run the above code and see the value of $matches it is an empty array. What am I doing wrong?
That's because you are looping through your $array and probably print the result after the loop.
So $matches just includes the matching elements of the last item in your $array.
But because 'no' is the last element, and it doesn't fulfill the regex requirements, $matches is empty.
To have a better understanding of what is happening, try to use print_r($matches) within your loop, after you called preg_matches().
And after that, try to call it after your loop and see the difference.
You need two variables. One is the result of the current match, and another is a list of all the matches. After each call you can push the result of the current match to the list.
$array = ['example1', '2example', 'no'];
$matches = [];
$var = "example";
foreach($array as $element)
{
if (preg_match("/.*$var.*/", $element, $match)) {
$matches[] = $match[0];
}
}
print_r($matches);
Extract the value of the u2 parameter from this URL using a regular expression. http://www.example.com?u1=US&u2=HA853&u3=HPA
<?php
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA"; //my url
$pattern='/u2=[0-9A-Za-z]*/'; //R.E that url value is only digit/Alphabet
preg_match($pattern,$subject,$match);
print_r($match[0]);
?>
Output:-
u2=HA853
How can i retrieve only HA853?
The 0 group is everything that the regex matched so either use \K to ignore the previous matches of the regex,
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA"; //my url
$pattern='/u2=\K[0-9A-Za-z]*/'; //R.E that url value is only digit/Alphabet
preg_match($pattern,$subject,$match);
print_r($match[0]);
or use a second capture group:
...
$pattern='/u2=([0-9A-Za-z]*)/'; //R.E that url value is only digit/Alphabet
...
print_r($match[1]);
Why you'd need to do that though is unclear to me, http://php.net/manual/en/function.parse-str.php, seems like a simpler approach.
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA";
parse_str($subject, $output);
echo $output['u2'];
Demo: https://3v4l.org/gR4cb
Other way is to use parse_url,http://php.net/manual/en/function.parse-url.php
$subject="http://www.example.com?u1=US&u2=HA853&u3=HPA";
$query_string = parse_url($subject, PHP_URL_QUERY); // get query string
$parameters = explode('&', $query_string); //Explode with &
$array = array(); // define an empty array
foreach($parameters as $val)
{
$param= explode('=', $val);
$array[$param[0]] = $param[1];
}
echo $array['u2']; // outputs HA853
print_r($array);
Array
(
[u1] => US
[u2] => HA853
[u3] => HPA
)
I have an array of possible attributes:
$attributes = ['color','size'];
Part of my URL looks like this:
color-light-grey-size-xs
I would need to get an array of attributes and their values, ie:
$values = [
'color' => 'light-grey',
'size' => 'xs'
]
Is that doable with regex?
A Regular Expression which you have to feed its cluster of attributes ORed:
(\w++)(?>-(\w+-?(?(?!color|size)(?-1))*))
^^^^^^^^^^
Regex live demo
PHP code:
$str = "color-light-grey-test-size-xs";
$attrs = ['color', 'size'];
$array = [];
preg_replace_callback(
"/(\w++)(?>-(\w+-?(?(?!" . implode("|", $attrs) . ")(?-1))*))/",
function($matches) use (&$array) {
$array[$matches[1]] = rtrim($matches[2], '-');
},
$str
);
print_r($array);
PHP live demo
Note: Order is not important at all.
I will tell you something.
ONLY if you know that first value is color and second value is size you can match between it like:
\bcolor\-([\w\d\-]+)-size-([\w\d\-]+)\b
You will get array of 2 matches for color $1 and for size $2
BUT if you don't know how your URL will look, you are in big problem.
You must know what you expect for all URL's and made matches for every combination.
Here is live example: https://regex101.com/r/3daBXx/1
preg_match accepts a $matches argument as a reference. All the examples I've seen do not initialize it before it's passed as an argument. Like this:
preg_match($somePattern, $someSubject, $matches);
print_r($matches);
Isn't this error-prone? What if $matches already contains a value? I would think it should be initialized to an empty array before passing it in as an arg. Like this:
$matches = array();
preg_match($somePattern, $someSubject, $matches);
print_r($matches);
Am i just being paranoid?
There is no need to initialise $matches as it will be updated with the results. It is in effect a second return value from the function.
as Chris Lear said you don't need to initialize $matches. But if your pattern contains a capture group you want to use later, it is better to write:
$somePattern = '/123(456)/';
if (preg_match($somePattern, $someSubject, $matches)) {
print_r($matches[1]);
}
to avoid the error of undefined index in the result array. However, you can use isset($matches[1]) to check if the index exists.
I'm a beginner in regular expression so it didn't take long for me to get totally lost :]
What I need to do:
I've got a string of values 'a:b,a2:b2,a3:b3,a4:b4' where I need to search for a specific pair of values (ie: a2:b2) by the second value of the pair given (b2) and get the first value of the pair as an output (a2).
All characters are allowed (except ',' which seperates each pair of values) and any of the second values (b,b2,b3,b4) is unique (cant be present more than once in the string)
Let me show a better example as the previous may not be clear:
This is a string: 2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,never:0
Searched pattern is: 5
I thought, the best way was to use function called preg_match with subpattern feature.
So I tried the following:
$str = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
$re = '/(?P<name>\w+):5$/';
preg_match($re, $str, $matches);
echo $matches['name'];
Wanted output was '5 minutes' but it didn't work.
I would also like to stick with Perl-Compatible reg. expressions as the code above is included in a PHP script.
Can anyone help me out? I'm getting a little bit desperate now, as Ive spent on this most of the day by now ...
Thanks to all of you guys.
$str = '2 minutes:2,51 seconds:51,5 minutes:5,10 minutes:10,15 minutes:51,never:0';
$search = 5;
preg_match("~([^,\:]+?)\:".preg_quote($search)."(?:,|$)~", $str, $m);
echo '<pre>'; print_r($m); echo '</pre>';
Output:
Array
(
[0] => 5 minutes:5
[1] => 5 minutes
)
$re = '/(?:^|,)(?P<name>[^:]*):5(?:,|$)/';
Besides the problem of your expression having to match $ after 5, which would only work if 5 were the last element, you also want to make sure that after 5 either nothing comes or another pair comes; that before the first element of the pair comes either another element or the beginning of the string, and you want to match more than \w in the first element of the pair.
A preg_match call will be shorter for certain, but I think I wouldn't bother with regular expressions, and instead just use string and array manipulations.
$pairstring = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
function match_pair($searchval, $pairstring) {
$pairs = explode(",", $str);
foreach ($pairs as $pair) {
$each = explode(":", $pair);
if ($each[1] == $searchval) {
echo $each[0];
}
}
}
// Call as:
match_pair(5, $pairstring);
Almost the same as #Michael's. It doesn't search for an element but constructs an array of the string. You say that values are unique so they are used as keys in my array:
$str = '2 minutes:2,5 minutes:5,10 minutes:10,15 minutes:15,20 minutes:20,30 minutes:30, never:0';
$a = array();
foreach(explode(',', $str) as $elem){
list($key, $val) = explode(':', $elem);
$a[$val] = $key;
}
Then accessing an element is very simple:
echo $a[5];