Extract number & text from string - php

I have this string:
There 10 items in shop A,
There 30 items in shop B.
I need extract number & text from the string. The result should:
array(
0 => 10 items,
1 => 30 items
);
I tried to use this regex:
\d+\s\/items
But it didn't work.

You should be using preg_match_all:
$string = 'There 10 items in shop A, There 30 items in shop B.';
$matches = null;
preg_match_all('/\d+\sitems/', $string, $matches);
var_dump($matches);
Would output:
array (size=1)
0 =>
array (size=2)
0 => string '10 items' (length=8)
1 => string '30 items' (length=8)

Related

preg_match_all for numbers in certain parts of string

Babylon 5 Season 4 Episode 13 Rumors Bargains and Lies 45
how i can extract numbers that comes after Season and the numbers that comes only after episode not any number after that. in the above example. i would want only 4 and 13 numbers using php using preg_match thanks in advance
You can do something like this:
$str = 'Babylon 5 Season 4 Episode 13 Rumors Bargains and Lies 45';
if (preg_match_all("/(Season|Episode) (\d.)/", $str, $matches)) {
var_dump($matches);
}
And it will output:
array (size=3)
0 =>
array (size=2)
0 => string 'Season 4 ' (length=9)
1 => string 'Episode 13' (length=10)
1 =>
array (size=2)
0 => string 'Season' (length=6)
1 => string 'Episode' (length=7)
2 =>
array (size=2)
0 => string '4 ' (length=2)
1 => string '13' (length=2)
You can have your Season and Episode values in an array m:
preg_match_all('/.*Season\s+(?<season>\d+)\s+Episode\s+(?<episode>\d+)/', $str, $m);
print 'Season: ' . $m['season'][0] . "\n";
print 'Episode: ' . $m['episode'][0] . "\n";
You can use regex look behind to capture numbers.
(?<=Season)\s*?\d+|(?<=Episode)\s*?\d+
It should capture 4 and 13.
See https://regex101.com/r/JVOUOw/2

How to limit a variable search to a single line of text?

Considering this sample text:
grupo1, tiago1A, bola1A, mola1A, tijolo1A, pedro1B, bola1B, mola1B, tijolo1B, raimundo1C, bola1C, mola1C, tijolo1C, joao1D, bola1D, mola1D, tijolo1D, felipe1E, bola1E, mola1E, tijolo1E,
grupo2, tiago2A, bola2A, mola2A, tijolo2A, pedro2B, bola2B, mola2B, tijolo2B, raimundo2C, bola2C, mola2C, tijolo2C, joao2D, bola2D, mola2D, tijolo2D, felipe2E, bola2E, mola2E, tijolo2E,
grupo3, tiago3A, bola3A, mola3A, tijolo3A, pedro3B, bola3B, mola3B, tijolo3B, raimundo3C, bola3C, mola3C, tijolo3C, joao3D, bola3D, mola3D, tijolo3D, felipe3E, bola3E, mola3E, tijolo3E,
grupo4, tiago4A, bola4A, mola4A, tijolo4A, pedro4B, bola4B, mola4B, tijolo4B, raimundo4C, bola4C, mola4C, tijolo4C, joao4D, bola4D, mola4D, tijolo4D, felipe4E, bola4E, mola4E, tijolo4E,
grupo5, tiago5A, bola5A, mola5A, tijolo5A, pedro5B, bola5B, mola5B, tijolo5B, raimundo5C, bola5C, mola5C, tijolo5C, joao5D, bola5D, mola5D, tijolo5D, felipe5E, bola5E, mola5E, tijolo5E,
I would like to capture the 20 values that follow grupo3 and store them in groups of 4.
I am using this: (Demo)
/grupo3,((.*?),(.*?),(.*?),(.*?)),/
but this only returns the first 4 comma separated values after grupo3.
I need generate this array structure:
Match 1
Group 1 tiago3A
Group 2 bola3A
Group 3 mola3A
Group 4 tijolo3A
Match 2
Group 1 pedro3B
Group 2 bola3B
Group 3 mola3B
Group 4 tijolo3B
Match 3
Group 1 raimundo3C
Group 2 bola3C
Group 3 mola3C
Group 4 tijolo3C
Match 4
Group 1 joao3D
Group 2 bola3D
Group 3 mola3D
Group 4 tijolo3D
Match 5
Group 1 felipe3E
Group 2 bola3E
Group 3 mola3E
Group 4 tijolo3E
You can try the following:
/,(.*?),(.*?),(.*?),(.*?),.*?$/m
the /m in the end indicates the flag for multi-line and $ before that indicates end of line. Demo
Edit: For getting every 4 elements only form the 3rd paragraph
/grupo3,((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)),/
Demo
And you can get the desired output in PHP like:
preg_match('/grupo3,((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)), ((.*?),(.*?),(.*?),(.*?)),/', $str, $matches);
$groups = [];
unset($matches[0]);
$matches = array_values($matches);
$count = count($matches);
$j=0;
for($i=1;$i<$count;$i++)
{
if($i%5 == 0)
{
$j++;
continue;
}
$groups[$j][] = $matches[$i];
}
var_dump($groups);
Output will be something like:
array (size=5)
0 =>
array (size=4)
0 => string ' tiago3A' (length=8)
1 => string ' bola3A' (length=7)
2 => string ' mola3A' (length=7)
3 => string ' tijolo3A' (length=9)
1 =>
array (size=4)
0 => string 'pedro3B' (length=7)
1 => string ' bola3B' (length=7)
2 => string ' mola3B' (length=7)
3 => string ' tijolo3B' (length=9)
2 =>
array (size=4)
0 => string 'raimundo3C' (length=10)
1 => string ' bola3C' (length=7)
2 => string ' mola3C' (length=7)
3 => string ' tijolo3C' (length=9)
3 =>
array (size=4)
0 => string 'joao3D' (length=6)
1 => string ' bola3D' (length=7)
2 => string ' mola3D' (length=7)
3 => string ' tijolo3D' (length=9)
4 =>
array (size=4)
0 => string 'felipe3E' (length=8)
1 => string ' bola3E' (length=7)
2 => string ' mola3E' (length=7)
3 => string 'tijolo3E' (length=0)
Please forgive the lateness of this answer. This is the comprehensive answer with a clean/direct solution that I would have posted earlier if this page wasn't put on hold. This is as refined a solution as I can devise without knowing more about how your input data is generated/accessed.
The input:
$text='grupo1, tiago1A, bola1A, mola1A, tijolo1A, pedro1B, bola1B, mola1B, tijolo1B, raimundo1C, bola1C, mola1C, tijolo1C, joao1D, bola1D, mola1D, tijolo1D, felipe1E, bola1E, mola1E, tijolo1E,
grupo2, tiago2A, bola2A, mola2A, tijolo2A, pedro2B, bola2B, mola2B, tijolo2B, raimundo2C, bola2C, mola2C, tijolo2C, joao2D, bola2D, mola2D, tijolo2D, felipe2E, bola2E, mola2E, tijolo2E,
grupo3, tiago3A, bola3A, mola3A, tijolo3A, pedro3B, bola3B, mola3B, tijolo3B, raimundo3C, bola3C, mola3C, tijolo3C, joao3D, bola3D, mola3D, tijolo3D, felipe3E, bola3E, mola3E, tijolo3E,
grupo4, tiago4A, bola4A, mola4A, tijolo4A, pedro4B, bola4B, mola4B, tijolo4B, raimundo4C, bola4C, mola4C, tijolo4C, joao4D, bola4D, mola4D, tijolo4D, felipe4E, bola4E, mola4E, tijolo4E,
grupo5, tiago5A, bola5A, mola5A, tijolo5A, pedro5B, bola5B, mola5B, tijolo5B, raimundo5C, bola5C, mola5C, tijolo5C, joao5D, bola5D, mola5D, tijolo5D, felipe5E, bola5E, mola5E, tijolo5E,';
The method: (PHP Demo)
var_export(preg_match('/^grupo3, \K.*(?=,)/m',$text,$out)?array_chunk(explode(', ',$out[0]),4):'fail');
Use preg_match() to extract the single line, then use explode() to split the string on "comma space", then use array_chunk() to store in an array of 5 subarrays containing 4 elements each.
The pattern targets grupo3, at the start of the line, then restarts the full match using \K then greedily matches every non-newline character and stops just before the last comma in the line. The positive lookahead (?=,) doesn't store the final comma in the full string match.
(Pattern Demo)
My method does not retain any leading and trailing spaces, just the values themselves.
Output:
array (
0 =>
array (
0 => 'tiago3A',
1 => 'bola3A',
2 => 'mola3A',
3 => 'tijolo3A',
),
1 =>
array (
0 => 'pedro3B',
1 => 'bola3B',
2 => 'mola3B',
3 => 'tijolo3B',
),
2 =>
array (
0 => 'raimundo3C',
1 => 'bola3C',
2 => 'mola3C',
3 => 'tijolo3C',
),
3 =>
array (
0 => 'joao3D',
1 => 'bola3D',
2 => 'mola3D',
3 => 'tijolo3D',
),
4 =>
array (
0 => 'felipe3E',
1 => 'bola3E',
2 => 'mola3E',
3 => 'tijolo3E',
),
)
p.s. If the search term ($needle) is to be dynamic, you can use something like this to achieve the same result: (PHP Demo)
$needle='grupo3';
// if the needle may include any regex-sensitive characters, use preg_quote($needle,'/') at $needle
var_export(preg_match('/^'.$needle.', \K.*(?=,)/m',$text,$out)?array_chunk(explode(', ',$out[0]),4):'fail');
/* or this is equivalent...
if(preg_match('/^'.$needle.', \K.*(?=,)/m',$text,$out)){
$singles=explode(', ',$out[0]);
$groups=array_chunk($singles,4);
var_export($groups);
}else{
echo 'fail';
}
*/

array_rand returning same value

I am having a problem returning random array keys if the specified number of entries is the same as the number of items in the array.
$rdm = array_rand($similar_product_array, 4);
will always return key values 0, 1, 2, 3 if there is 4 items in the array.
for example:
// Items in array
array (size=4)
0 => string 'Batman Heroes Edition Nendoroid' (length=31)
1 => string 'Oberyn' (length=6)
2 => string 'White Walker' (length=12)
3 => string 'Avengers Age of Ultron Hulk' (length=27)
// "randomly" generated array keys is always 0 , 1, 2, 3
array (size=4)
0 => int 0
1 => int 1
2 => int 2
3 => int 3
however, if i have:
$rdm = array_rand($similar_product_array, 3);
// Returns randomly as expected
array (size=3)
0 => int 0
1 => int 2
2 => int 3
it will return randomly generated keys as it should.
What could i be doing wrong here?
You misunderstood purpose of array_rand() function, it is supposed to give you random entries from array, but not in random order. That means that if you are asking for 4 random items from array with 4 items, it will always return all the items (in the original order).
If you just need to change randomly the order of array entries, use shuffle() function, for example in this way:
$array_copy = $array;
shuffle($array_copy);
$rdm = array_rand($array_copy, <how_many_you_need>);

Regex Extracting After the Match

preg_match('/\$(\d+\.\d+)/',$message,$keywords);
dd($keywords);
Hi , have got a few questions
1) Is it possible to detect/extract the text after the regular expression? eg I'm trying to detect $1.20 possible to detect the text after it eg per hour , /hr , per hr, / hour.
1.1) Maybe like Extract 20 characters after the match
1.2) Possible to know the position of the match if i cant extract?
$100000/hour test test test
Extract test test tst
1) Put everything you want to extract in the regex, like this:
preg_match('#\$(\d+\.\d+)(\s+per hour|\s*/hr|\s+per hr|\s*/hour)?#',$message,$keywords);
You'll get the amount in $keywords[1] and the other piece of text in $keywords[2];
1.1) Use /\$(\d+\.\d+)(.{,20})/ to get at most 20 characters in the second match (if you remove the comma it will match only if after the amount there are at least 20 characters).
1.2) Use the $flags parameter of preg_match(): preg_match('/\$(\d+\.\d+)/',$message,$keywords,PREG_OFFSET_CAPTURE);. Check print_r($keywords) to see how the matched values and their offsets are returned
You probably need to find all the appearances. In this case use preg_match_all().
Try this:
$re = '~\$(\d+\.?\d+)/?(\w+)?~m';
$str = "$100000/hour\n$100.2000/min";
preg_match_all($re, $str, $matches);
var_dump($matches);
Demo on regex101
Output
array (size=3)
0 =>
array (size=2)
0 => string '$100000/hour' (length=12)
1 => string '$100.2000/min' (length=13)
1 =>
array (size=2)
0 => string '100000' (length=6)
1 => string '100.2000' (length=8)
2 =>
array (size=2)
0 => string 'hour' (length=4)
1 => string 'min' (length=3)

Regex to get currency and amount from string

I have an Regex with me preg_match('/(?<=\$)\d+(\.\d+)?\b/', $str, $regs which return me the amount in a currency, but what i am trying is to get the symbol associated with the amount too.
1) E.g. the string is $300.00 asking price should return $300.00 but now it returns 300
2) E.g. the string is EUR 300.00 should return EUR300.00 but now it returns 300
Simply i want the currency with amount.
Thanks
First, you match the currency which can be either $ or EUR, followed by optional white space:
(?:EUR|[$])\s*
Then, match the main digit group, followed by an optional period and two digits:
\d+(?:\.\d{2})?
In total we get this:
$pattern = '/(?:EUR|[$])\s*\d+(?:\.\d{2})?/';
if (preg_match($pattern, $string, $matches)) {
echo $matches[0];
}
Try this one
$str = "$300.00 asking price";
preg_match('/^([\$]|EUR|€)\s*([0-9,\s]*\.?[0-9]{0,2})?+/', $str, $regs);
Outputs
array (size=3)
0 => string '$300.00' (length=7)
1 => string '$' (length=1)
2 => string '300.00' (length=6)
array (size=3)
0 => string 'EUR 300.00' (length=10)
1 => string 'EUR' (length=3)
2 => string '300.00' (length=6)
Try with
/(\$|EUR)\s*(\d*\.\d+)?\b/
If you want just the amount part for any Symbol :
preg_match_all("/([0-9]+[.]*)/", $t, $output_array);
$output_array=implode("",$output_array[0]);
" €12451.5651$Euro " will output: 12451.5651

Categories