How do i match this with REGEXP and PHP ?
"s:6:\"[\"50\"]\";",
"s:5:\"[\"1\"]\";"
I want to match numbers between : [\"50\"] this only or could be one or more.
I have a pattern and want to take only numbers from json_encode value also serialize() in php this is code :
$result = [];
foreach($impressions as $impression) {
preg_match_all('/\x5C/', $impression->subcategories, $result);
}
return $result;
if no preg_match then here is result :
"s:6:\"[\"50\"]\";",
"s:5:\"[\"1\"]\";"
I am using this to match only digit where \ is so i can take number only like 50 or 1
Any idea how i can pic number with regular expressions ? value hex not works '/\x5C/' showing me result blank but here : Works fine if i put result and test with same REGEXP.
First of all, you can not go through an array of strings that way with preg_match_all – your $result array gets overwritten in each loop iteration.
And then, you need to capture the numbers you want to see in your result set. To do that, you must mask the [, ] and \ characters each with another \ – and then capture the digits in the middle by putting them in ( and )
$impressions[] = "s:6:\"[\"50\"]\";";
$impressions[] = "s:5:\"[\"1\"]\";";
foreach($impressions as $impression) {
preg_match_all('#\[\\"([0-9]+)\\"\]#', $impression, $matches); // I chose # as delimiter
// here – with so many \ involved, we don’t need / around it to add to the confusion
$results[] = $matches; // $matches will be overwritten in each iteration, so we
// preserve its content here by putting it into the $results array
}
var_dump($results);
Related
I have an array of arrays like:
$array = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]]
Now, I want to implode this array such that it would return something like this:
COTV_LITE(1800)
COTV_PREMIUM(2200)
How do I achieve this? Calling just the implode() function did not work:
implode ('<br>', $array);
You can call array_map() to implode the nested arrays:
echo implode('<br>', array_map(function($a) { return implode(' ', $a); }, $array));
DEMO
output:
1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)
You can use variable length arguments variadic in PHP >= 5.6
Option1
$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
echo implode(' ',array_merge(...$items));
Output
1. COTV_LITE(1800) 2. COTV_PREMIUM(2200)
This is more of a precursor for the next option.
Option2
If you want to get a bit more creative you can use preg_replace too:
$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
$replace = [
'/^(\d+\.)$/' => '<li>\1 ',
'/^(\w+\(\d+\))$/' => '\1</li>'
];
echo '<ul>'.implode(preg_replace(array_keys($replace),$replace,array_merge(...$items))).'</ul>';
Output
<ul><li>1. COTV_LITE(1800)</li><li>2. COTV_PREMIUM(2200)</li></ul>
Option3
And lastly using an olordered list, which does the numbers for you. In this case we only need the second item from the array (index 1):
$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
echo '<ol><li>'.implode('</li><li>',array_column($items,1)).'</li></ol>';
Output
<ol><li>COTV_LITE(1800)</li><li>COTV_PREMIUM(2200)</li></ol>
Personally, I would put it in the ol that way you don't have to worry about the order of the numbers, you can let HTML + CSS handle them. Also it's probably the easiest and most semantically correct way, But I don't know if the numbering in the array has any special meaning or not.
In any case I would most definitely put this into a list to render it to HTML. This will give you a lot more options for styling it, later.
Update
want to use option 1. But how do I put each option on a different line using <br>
That one will put the <br> between each array element:
echo implode('<br>',array_merge(...$items));
Output
1.<br>COTV_LITE(1800)<br>2.<br>COTV_PREMIUM(2200)
The only way to easily fix that (while keeping the array_merge) is with preg_replace, which is the second one. So I will call this:
Option 1.2
$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
echo implode(preg_replace('/^(\w+\(\d+\))$/',' \1<br>',array_merge(...$items)));
Output
1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)<br>
Sandbox
Basically there is no way to tell where the end item is after merging them. That operation effectively flattens the array out and gives us something like this:
["1.","COTV_LITE(1800)","2.","COTV_PREMIUM(2200)"]
So that Regex does this 'COTV_PREMIUM(2200)' becomes ' COTV_PREMIUM(2200)<br>'. This is just a way of changing that without having to dip into the array with some logic or something. WE wind up with this modification to the array:
["1."," COTV_LITE(1800)<br>","2."," COTV_PREMIUM(2200)<br>"]
Then with implode we just flatten it again into a string:
"1. COTV_LITE(1800)<br>2. COTV_PREMIUM(2200)<br>"
The Regex ^(\w+\(\d+\))$
^ - Match start of string
(...) - capture group 1
\w+ - match any working character a-zA-Z0-9_ one or more, eg. COTV_PREMIUM
\( - match the ( literally
\d+ - match digits 0-9 one or more, eg 2200
\) - match the ) literally
$ - match end of string
So this matches the pattern of the second (or even) items in the array, then we replace that with this:
The Replacement ' \1<br>'
{space} - adds a leading space
\1 - the value of capture group 1 (from above)
<br> - append a line break
Hope that makes sense. This should work as long as they meet that pattern. Obviously we can adjust the pattern, but with such a small sample size it's hard for me to know what variations will be there.
For example something as simple as (.+\))$ will work TestIt. This one just looks for the ending ). We just need somethng to capture all of the even ones, while not matching the odd. Regular expressions can be very confusing the first few times you see them, but they are extremely powerful.
PS - I added a few links to the function names, these go the the PHP documentation page for them.
Cheers!
Try this
$items = [["1.","COTV_LITE(1800)"],["2.","COTV_PREMIUM(2200)"]];
$imploded = [];
foreach($items as $item) {
$item_entry = implode(' ', $item);
echo $item_entry . '<br/>'; // display items
$imploded[] = $item_entry;
}
// your desired result is in $imploded variable for further use
I thought I had this working; however after further evaluation it seems it's not working as I would have hoped it was.
I have a query pulling back a string. The string is a comma separated list just as you see here:
(1,145,154,155,158,304)
Nothing has been added or removed.
I have a function that I thought I could use preg_match to determine if the user's id was contained within the string. However, it appears that my code is looking for any part.
preg_match('/'.$_SESSION['MyUserID'].'/',$datafs['OptFilter_1']))
using the same it would look like such
preg_match('/1/',(1,145,154,155,158,304)) I would think. After testing if my user id is 4 the current code returns true and it shouldn't. What am I doing wrong? As you can see the id length can change.
It's better to have all your IDs in an array then checking if a desired ID is existed:
<?php
$str = "(1,145,154,155,158,304)";
$str = str_replace(array("(", ")"), "", $str);
$arr = explode(',', $str);
if(in_array($_SESSION['MyUserID'], $arr))
{
// ID existed
}
As your string - In dealing with Regular Expressions, however it's not recommended here, below regex will match your ID if it's there:
preg_match("#[,(]$ID[,)]#", $str)
Explanations:
[,(] # a comma , or opening-parenthesis ( character
$ID # your ID
[,)] # a comma , or closing-parenthesis ) character
I am filtering database results with a query string that looks like this:
attribute=operator(value|optional value)
I'll use
$_GET['attribute'];
to get the value.
I believe the right approach is using regex to get matches on the rest.
The preferred output would be
print_r($matches);
array(
1 => operator
2 => value
3 => optional value
)
The operator will always be one word and consist of letters: like(), between(), in().
The values can be many different things including letters, numbers, spaces commas, quotation marks, etc...
I was asked where my code was failing and didn't include much code because of how poorly it worked. Based on the accepted answer, I was able to whip up a regex that almost works.
EDIT 1
$pattern = "^([^\|(]+)\(([^\|()]+)(\|*)([^\|()]*)";
Edit 2
$pattern = "^([^\|(]+)\(([^\|()]+)(\|*)([^\|()]*)"; // I thought this would work.
Edit 3
$pattern = "^([^\|(]+)\(([^\|()]+)(\|+)?([^\|()]+)?"; // this does work!
Edit 4
$pattern = "^([^\|(]+)\(([^\|()]+)(?:\|)?([^\|()]+)?"; // this gets rid of the middle matching group.
The only remaining problem is when the 2nd optional parameter does not exist, there is still an empty $matches array.
This script, with the input "operator(value|optional value)", returns the array you expect:
<?php
$attribute = $_GET['attribute'];
$result = preg_match("/^([\w ]+)\(([\w ]+)\|([\w ]*)\)$/", $attribute, $matches);
print($matches[1] . "\n");
print($matches[2] . "\n");
print($matches[3] . "\n");
?>
This assumes your "values" match [\w ] regexp (all word characters plus space), and that the | you specify is a literal |...
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.
I have a database of more than 70000 records and its primary key value started from 1 single digit.
So I want user have to type nm0000001 instead of 1 in url.And in code part I have to discard the rest of the value except 1.
But my problem is i want this type of things having 9 letters in the string and the pattern is like this
1 - nm0000001
9 - nm0000009
10 - nm0000010
2020 - nm0002020
And from the above pattern i want only the digits like 1,9,10,2020 in php.
Here:
$i = (int)substr($input, 2);
No reason to use regexes at all.
Anyway, if you're insisting on using regexp, then:
$input = 'nm0002020';
preg_match('~0*(\d+)$~', $input, $matches);
var_dump($matches[1]);
Assuming the value is received in the URL as a querystring parameter, that is, passed via $_GET['id'] or some other name than id:
// Trim the "nm" off the front
$pk = substr($_GET['id'],2);
// And parse out an integer value.
$id = intval($pk);
There's absolutely no use for regular expressions in this -- use sprintf("nm%07d", ...) to format and just substr and a cast to int to parse.
This function will do the trick:
function extractID($pInput)
{
$Matches = array();
preg_match('/^nm0*(.*)$/', $pInput, $Matches);
return intval($Matches[1]);
}
Here's why /^nm0+(.*)$/ works:
The line must start (^) with exactly one nm
The pattern must continue with at least one 0
At the first non-zero character after nm0..., capture the value (that's the job of the parentheses)
Continue until the end of the line ($)