Finding decimal numbers in a string via regex - php

I got decimal problem while I parsing my command. 12.90 has been parsed wrongly:
// My command
$cmd = 'CREATE product price:12.90, name: "Create me"';
// My parser
preg_match_all('/\w+|".*?"|(?!\s)\W/', $cmd, $list);
Output:
Array
(
[0] => CREATE
[1] => product
[2] => price
[3] => :
[4] => 12 // << problem starts here
[5] => .
[6] => 90
[7] => ,
[8] => name
[9] => :
[10] => "Create me"
)
I am looking for this output:
Array
(
[0] => CREATE
[1] => product
[2] => price
[3] => :
[4] => 12.90 // supposed
[5] => ,
[6] => name
[7] => :
[8] => "Create me"
)
So, how can I solve this problem?
Edit: (the better solution)
Guys, I accepted Jesse's answer according to my question. But I realized it is not good enough for my complex commands. It's better, because it works with both decimals like 12.90 and alias names like p.price. So just look at my example and parser below for it. I hope this help someone.
// My command
$cmd = 'GET `order` -o, product -p
LIST o.user_id, o.product_id, p.name, p.price
REL o.order_id = 3 AND p.price > 12.90';
// My complex command:
preg_match_all('/[0-9_\.]+|\w+|".*?"|`.*?`|\'.*?\'|!=|<=|>=|(?!\s)\W/', $cmd, $list);
// Output:
Array
(
[0] => Array
(
[0] => GET
[1] => `order`
[2] => -
[3] => o
[4] => ,
[5] => product
[6] => -
[7] => p
[8] => LIST
[9] => o
[10] => .
[11] => user_id
[12] => ,
[13] => o
[14] => .
[15] => product_id
[16] => ,
[17] => p
[18] => .
[19] => name
[20] => ,
[21] => p
[22] => .
[23] => price
[24] => REL
[25] => o
[26] => .
[27] => order_id
[28] => =
[29] => 3
[30] => AND
[31] => p
[32] => .
[33] => price
[34] => >
[35] => 12.90
)
)

\w class does not include the . so the "quick" fix is to add it as follows:
preg_match_all('/[\w.]+|".*?"|(?!\s)\W/', $cmd, $list);
Do you have any other requirements regarding where the period is allowed? (ie only matching when it is between numbers?). If so, you may need to make the matching more specialized.
The biggest thing thing that jumps out at me is if the period would be used as delimiter for some other aspect of your parser. If the RE that you gave is your entire parser you are probably ok.

This works for me:
/[a-zA-Z0-9_\.]+|:|,|".*?"/

Related

Alternative values should store in alternative position in array in php

When the values fetching from the mysql the values will be stored in series order in the array. But i want the values to store in the array in alternative position. Here some individual values from table
course_id('1') values
Array (
[0] => 15BCA01 [1] => 15BCA02 [2] => 15BCA03 [3] => 15BCA04 [4] => 15BCA05
[5] => 15BCA06 [6] => 15BCA07 [7] => 15BCA08 [8] => 15BCA09 [9] => 15BCA10
[10] => 15BCA11
)
course_id('2') values:
Array (
[0] => 15MCA01 [1] => 15MCA02 [2] => 15MCA03 [3] => 15MCA04 [4] => 15MCA05
)
course_id('3') values:
Array (
[0] => 15MBA01 [1] => 15MBA02 [2] => 15MBA03 [3] => 15MBA04 [4] => 15MBA05
)
course_id('4') values:
Array (
[0] => 15MSC01 [1] => 15MSC02 [2] => 15MSC03
)
course_id('5') values:
Array (
[0] => 15TAM01 [1] => 15TAM02
)
when i execute the mysql command
select register_number from master where master_course_id in('1','2','3','4','5');
Current Output i am getting (as usual in series):
Array (
[0] => 15BCA01 [1] => 15BCA02 [2] => 15BCA03 [3] => 15BCA04 [4] => 15BCA05
[5] => 15BCA06 [6] => 15BCA07 [7] => 15BCA08 [8] => 15BCA09 [9] => 15BCA10
[10] => 15BCA11 [11] => 15MCA01 [12] => 15MCA02 [13] => 15MCA03 [14] => 15MCA04
[15] => 15MCA05 [16] => 15MBA01 [17] => 15MBA02 [18] => 15MBA03 [19] => 15MBA04
[20] => 15MBA05 [21] => 15MSC01 [22] => 15MSC02 [23] => 15MSC03 [24] => 15TAM01
[25] => 15TAM02
)
Desired Output I want(alternative position):
Array (
[0] => 15BCA01 [1] => 15MCA01 [2] => 15BCA02 [3] => 15MCA02 [4] => 15BCA03
[5] => 15MCA03 [6] => 15BCA04 [7] => 15MCA04 [8] => 15BCA05 [9] => 15MCA05
[10] => 15BCA06 [11] => 15MBA01 [12] => 15BCA07 [13] => 15MBA02 [14] => 15BCA08
[15] => 15MBA03 [16] => 15BCA09 [17] => 15MBA04 [18] => 15BCA10 [19] => 15MBA05
[20] => 15BCA11 [21] => 15MSC01 [22] => 15TAM01 [23] => 15MSC02 [24] => 15TAM02
[25] => 15MSC03
)
If the first value in the array from course_id ('1') means the second values should be from course_id ('2') alternatively they should add in array. If the course_id ('1') completed the next course_id('3') should start to add with current course_id ('2'). Like wise all the course_id values should add in the array alternatively. How to achieve this in php
In MySQL you need to use a user-defined variable to add ordering within the master_course_id groups.
SELECT register_number
FROM (
SELECT master_course_id, register_number,
#position := IF(master_course_id = #prev_course, #position+1, 1) AS position,
#prev_course := master_course_id
FROM (SELECT * FROM master
WHERE master_course_id IN ('1', '2', '3', '4', '5')
ORDER BY master_course_id, register_number) AS m,
CROSS JOIN (SELECT #position := 0, #prev_course := null) AS vars
) AS t
ORDER BY position, master_course_id
The subquery adds an extra position column that counts up sequentially within each course ID. Then the outer query reorders everything by position first, then by course ID.

PHP - How would one go about combining 3 different arrays into one

So i have 3 different ( yet they share some similarities ) and i would like to combine these into one to perform some calculations
Array
(
[0] => Array
(
[0] => Agent
[1] => Answered
[2] => Missed
[3] => Contribution
[4] => Per Hour
[5] => Total Ring Time
[6] => Mean Ring Time
[7] => Total Talk Time
[8] => Mean Talk Time
[9] => Total Wrap Time
[10] => Mean Wrap Time
[11] => Total Session Time
[12] => Mean Session Time
[13] => Number of Sessions
[14] => % Util
[15] => Agent Hang-Ups
[16] => Caller Hang-Ups
[17] => Agent Hang-Ups Percent
[18] => Caller Hang-Ups Percent
)
[1] => Array
(
[0] => Amber
[1] => 16
[3] => 2.0%
[4] => 0.2
[5] => 28.6
[6] => 1.8
[7] => 1861.1
[8] => 116.3
[9] => 0.0
[10] => 0.0
[11] => 234862.2
[12] => 3403.8
[13] => 69.0
[14] => 0.8%
[15] => 10
[16] => 6
[17] => 62.5%
[18] => 37.5%
)
[2] => Array
(
[0] => Amie
[1] => 106
[3] => 13.5%
[4] => 3.0
[5] => 721.7
[6] => 6.8
[7] => 12268.0
[8] => 115.7
[9] => 0.0
[10] => 0.0
[11] => 127011.0
[12] => 6350.5
[13] => 20.0
[14] => 9.7%
[15] => 54
[16] => 52
[17] => 50.9%
[18] => 49.1%
)
)
Array 2
Array
(
[0] => Array
(
[0] => Agent
[1] => Answered
[2] => Missed
[3] => Contribution
[4] => Per Hour
[5] => Total Ring Time
[6] => Mean Ring Time
[7] => Total Talk Time
[8] => Mean Talk Time
[9] => Total Wrap Time
[10] => Mean Wrap Time
[11] => Total Session Time
[12] => Mean Session Time
[13] => Number of Sessions
[14] => % Util
[15] => Agent Hang-Ups
[16] => Caller Hang-Ups
[17] => Agent Hang-Ups Percent
[18] => Caller Hang-Ups Percent
)
)
Array 3
[0] => Array
(
[0] => Agent
[1] => Answered
[2] => Missed
[3] => Contribution
[4] => Per Hour
[5] => Total Ring Time
[6] => Mean Ring Time
[7] => Total Talk Time
[8] => Mean Talk Time
[9] => Total Wrap Time
[10] => Mean Wrap Time
[11] => Total Session Time
[12] => Mean Session Time
[13] => Number of Sessions
[14] => % Util
[15] => Agent Hang-Ups
[16] => Caller Hang-Ups
[17] => Agent Hang-Ups Percent
[18] => Caller Hang-Ups Percent
)
[1] => Array
(
[0] => (7312
[1] => 1
[3] => 0.0%
[4] => 459.8
[5] => 0.0
[6] => 0.0
[7] => 0.4
[8] => 0.4
[9] => 0.0
[10] => 0.0
[11] => 7.8
[12] => 2.6
[13] => 3.0
[14] => 5.5%
[15] => 1
[17] => 100.0%
[18] => 0.0%
)
[2] => Array
(
[0] => Amber
[1] => 414
[2] => 9
[3] => 9.3%
[4] => 6.3
[5] => 1880.1
[6] => 4.4
[7] => 65209.8
[8] => 157.5
[9] => 240.4
[10] => 0.6
[11] => 234862.2
[12] => 3403.8
[13] => 69.0
[14] => 27.8%
[15] => 290
[16] => 124
[17] => 70.0%
[18] => 30.0%
)
So in this example i have 3 arrays, all have the same first initial array. But these arrays can differ in size and they may not share the same people in in.
People can also be in different places so i.e.
Array 1 : Common -> Amber -> Amie
Array 2 : Common ->
Array 3 : Common -> 7312 -> Amber ->Amie
Now the final array should look like
Array 4 : Common -> 7312 -> Amber -> Amie
All the values from all arrays should also be combined so i.e:
Amber 1st array / 1st value : 16
Amber 2nd array / 2nd value : 414
Amber final array value : 414 + 16 = 430
Hopefully i have made question clear.
Basically, you sum up all the info you got, remove the headers. Then rebuild a new array with the info consolidation.
//merge all arrays, remove the first element, it is headers.
$my_total_array = array_merge(
array_splice($array1,1),
array_splice($array2,1),
array_splice($array3,1)
);
$myagents = array();
foreach($my_total_array as $agent){
if(!isset($myagents[$agent[0]])){
//Never met the agent, add them.
$myagents[$agent[0]] = $agent;
}else{
//We already seen the agent, do maths.
$myagents[$agent[0]][1]+=$agent[1];
//TODO: Apply consolidation rules for other fields.
}
}
//Put the headings back at the beggining.
array_unshift($myagents,$array1[0]);
print_r($myagents);
I hope this helps.
EDIT: From PHP Docs
Merges the elements of one or more arrays together so that the values
of one are appended to the end of the previous one. It returns the
resulting array.
If the input arrays have the same string keys, then the later value
for that key will overwrite the previous one. If, however, the arrays
contain numeric keys, the later value will not overwrite the original
value, but will be appended.

Twitter oauth getting friednds from std object class and checking with mysql database

I'm using abarahams oauth and I have been able to retrieve the std class object like so
stdClass Object
(
[ids] => Array
(
[0] => 15761916
[1] => 30144785
[2] => 382747195
[3] => 19399719
[4] => 15962388
[5] => 119513889
[6] => 18286505
[7] => 74829153
[8] => 20536157
[9] => 29877699
[10] => 242314486
[11] => 17813899
[12] => 18931678
[13] => 27791181
[14] => 13049362
[15] => 21845792
[16] => 136361303
[17] => 50184013
[18] => 169686021
[19] => 22733444
[20] => 30543716
[21] => 338084918
[22] => 18182384
[23] => 16213342
[24] => 5988062
[25] => 127640187
[26] => 181835231
[27] => 244189163
[28] => 38919338
[29] => 66644574
)
[next_cursor] => 0
[next_cursor_str] => 0
[previous_cursor] => 0
[previous_cursor_str] => 0
)
all these array value reside in a php variable $following
I want to perform a mysql query to check if value and see if there is a match in my database example
mysql_query( " Select id from user where oauth = '$following->ids[$i]' ");
to return my website ids of users. i want all the existing users in my databse who have oauth id to be pulled out and put in an array. i have tried using mysql_fetch assoc but if gived resource id #1,2 etc.
Any help would be appreciated

Regex match every character and newline

I want to filter some data using regex. As for now I have some text going over 2 lines and I tried to make the linebreak match with [^.*]. But it seems to not pass the newline and so it doesn't match any result on the second line. How can I include the linebreak? I tried something like [^\n\r.*] but it didn't worked out.
Description
You could use the 's' option which forces the dot to match all new line characters, or if you don't have control over the underlying code you could try:
([^.]|[.])
This will match every character. The dot will sometimes not match the carriage return, new line.
PHP example
<?php
$sourcestring="This is my.
super cool
test string";
preg_match_all('/([^.]|[.])/i',$sourcestring,$matches);
echo "<pre>".print_r($matches,true);
?>
$matches Array:
(
[0] => Array
(
[0] => T
[1] => h
[2] => i
[3] => s
[4] =>
[5] => i
[6] => s
[7] =>
[8] => m
[9] => y
[10] => .
[11] =>
[12] =>
[13] => s
[14] => u
[15] => p
[16] => e
[17] => r
[18] =>
[19] => c
[20] => o
[21] => o
[22] => l
[23] =>
[24] =>
[25] => t
[26] => e
[27] => s
[28] => t
[29] =>
[30] => s
[31] => t
[32] => r
[33] => i
[34] => n
[35] => g
)
[1] => Array
(
[0] => T
[1] => h
[2] => i
[3] => s
[4] =>
[5] => i
[6] => s
[7] =>
[8] => m
[9] => y
[10] => .
[11] =>
[12] =>
[13] => s
[14] => u
[15] => p
[16] => e
[17] => r
[18] =>
[19] => c
[20] => o
[21] => o
[22] => l
[23] =>
[24] =>
[25] => t
[26] => e
[27] => s
[28] => t
[29] =>
[30] => s
[31] => t
[32] => r
[33] => i
[34] => n
[35] => g
)
)

How to sort an array of items as numbers?

I have a number of files I am loading into a slideshow, I have them numbered by the client in the order that they'd like to be displayed.
I'm grabbing them with glob $pics = glob("images/slideshow/*.jpg", GLOB_NOSORT); but for some reason I'm getting the old Windows sorting bug, of 11 being sorted above 2.
For example,
Array
(
[0] => images/slideshow/1.jpg
[1] => images/slideshow/14.jpg
[2] => images/slideshow/15.jpg
[3] => images/slideshow/16.jpg
[4] => images/slideshow/18.jpg
[5] => images/slideshow/2.jpg
[6] => images/slideshow/20.jpg
[7] => images/slideshow/21.jpg
[8] => images/slideshow/22.jpg
[9] => images/slideshow/23.jpg
[10] => images/slideshow/24a.jpg
[11] => images/slideshow/25.jpg
[12] => images/slideshow/26.jpg
[13] => images/slideshow/29.jpg
[14] => images/slideshow/3.jpg
[15] => images/slideshow/36.jpg
[16] => images/slideshow/38.jpg
[17] => images/slideshow/4.jpg
[18] => images/slideshow/40.jpg
[19] => images/slideshow/41.jpg
[20] => images/slideshow/5.jpg
[21] => images/slideshow/6.jpg
[22] => images/slideshow/7.jpg
)
I've run it through asort() and I can't seem to find out why this isn't working, short of it being something about them being strings, rather than strictly numbers.
Check out natsort:
This function implements a sort algorithm that orders alphanumeric
strings in the way a human being would while maintaining key/value
associations.
$array2 = array("img12.png", "img10.png", "img2.png", "img1.png");
print_r($array2);
Array
(
[3] => img1.png
[2] => img2.png
[1] => img10.png
[0] => img12.png
)

Categories