Obtain specific data with preg_match_all - php

I have different texts which aren't well formatted, therefore I need a pattern which works with all of them and return some specific elements (text) from it. Let's say I have this text:
"AL TEST232 KW 12*/13*/17 TEST kw16TEST123 kw 15*"
and I want my preg_match_all() to return something like this:
Array
(
[0] => Array
(
[0] => AL TEST232
[1] => 12/13/17
)
[1] => Array
(
[0] => TEST
[1] => 16
)
[2] => Array
(
[0] => TEST123
[1] => 15
)
)
Is this possible with a single pattern?

You can use:
preg_match_all('~(\w[\s\w]*?\w)\s*kw\s*([\d/*]+)~', $input, $matches);
RegEx Demo

Related

Total disance multiple latitude and longitude points in php?

I am trying to print out the total distance in latitude between multiple points in php and printing out the result so I can then dump it into a mysql database. For example I have
MULTILINESTRING ((166.282008076887 -50.4981757000558,166.282014047837 -50.4981149924515,166.282009048641 -50.4981449926728,166.282021047737 -50.498071992073,166.281791047443 -50.4979599921101,166.281661047662 -50.4978739926141,166.281637048376 -50.4978479925945))
I can't get past exploding it at , then again at a space so I have $points[0] and $point[1] but I am stuck beyond that. I know how to get the distance between two points but how do I go beyond that?
You can split the string into Lat-Long pairs by splitting them around the comma delimiter.
$str="166.282008076887 -50.4981757000558,166.282014047837 -50.4981149924515,166.282009048641 -50.4981449926728,166.282021047737 -50.498071992073,166.281791047443 -50.4979599921101,166.281661047662 -50.4978739926141,166.281637048376 -50.4978479925945";
$latLongArray=explode(",",$str);
echo "<pre>";
print_r($latLongArray);
echo "</pre>";
The above splits the string into space separated Lat/Long pairs as follows -
Array
(
[0] => 166.282008076887 -50.4981757000558
[1] => 166.282014047837 -50.4981149924515
[2] => 166.282009048641 -50.4981449926728
[3] => 166.282021047737 -50.498071992073
[4] => 166.281791047443 -50.4979599921101
[5] => 166.281661047662 -50.4978739926141
[6] => 166.281637048376 -50.4978479925945
)
Next, you split them along the space, and save each lat/long array pair in a new array. You can use an associative array or json, the choice is yours.
$finalArray=array();
for($i=0;$i<count($latLongArray);$i++){
$tempStr=str_replace(" ",",",$latLongArray[$i]);
$tempArr=explode(",",$tempStr);
array_push($finalArray,$tempArr);
}
echo "<pre>";
print_r($finalArray);
echo "</pre>";
This prints the Lat/Long pairs saved in the final array -
Array
(
[0] => Array
(
[0] => 166.282008076887
[1] => -50.4981757000558
)
[1] => Array
(
[0] => 166.282014047837
[1] => -50.4981149924515
)
[2] => Array
(
[0] => 166.282009048641
[1] => -50.4981449926728
)
[3] => Array
(
[0] => 166.282021047737
[1] => -50.498071992073
)
[4] => Array
(
[0] => 166.281791047443
[1] => -50.4979599921101
)
[5] => Array
(
[0] => 166.281661047662
[1] => -50.4978739926141
)
[6] => Array
(
[0] => 166.281637048376
[1] => -50.4978479925945
)
)
Hope this helps.
Added later --
$totalDistance=0;
for($i=0;$i<count($finalArray);$i++){
$totalDistance+= calculateDistance($finalArray[$i],$finalArray[$i+1]);
}
echo $totalDistance;
function calculateDistance($pointA,$pointB){
// calculate distance between the two points
// ie, $pointA->Lat/Long, $pointB->Lat/Long
}

Parsing digit which has three letters with preg_match

I have a string which I have to parse digit which has three letters but I want to use same pattern using preg_match.
Here is my code can anybody help me out.
$string=" AMOUNT - 10.00CAD 0.50XGA 1.00XQA";
if(preg_match('/^\s+AMOUNT\s+\-\s+\d+[.]\d+[A-Z]{3}\s+((?J)(?<amount>\d+[.]\d+)(XGA)?(?J)\s+(?<amount>\d+[.]\d+)(XQA))/',$string,$m))
{
print_r($m);
}
I'd use preg_match_all like that:
$string=" AMOUNT - 10.00CAD 0.50XGA 1.00XQA";
if(preg_match_all('/^\s+AMOUNT\s+-\s+(*SKIP)(*F)|(\d+\.\d+)[A-Z]{3}\b/', $string, $m)) {
print_r($m);
}
Output:
Array
(
[0] => Array
(
[0] => 10.00CAD
[1] => 0.50XGA
[2] => 1.00XQA
)
[amount] => Array
(
[0] => 10.00
[1] => 0.50
[2] => 1.00
)
[1] => Array
(
[0] => 10.00
[1] => 0.50
[2] => 1.00
)
)

Regex with unknown character length

Simple question for you folks.
Sorry that I have to ask it.
On my website, I want to use signatures at "random" places in my text. The problem is, There could be multiple DIFFERENT signatures in this given string.
The signature code is ~~USERNAME~~
So anything like
~~timtj~~
~~foobar~~
~~totallylongusername~~
~~I-d0n't-us3-pr0p3r-ch#r#ct3r5~~
I have tried using preg_match for this, with no success. I understand that the third parameter is used to store the matches, but I can not properly get a match because of the format.
Should I not use preg_match, or am I just not able to use signatures in this manner?
You could make use of preg_match_all and with this modified regex
preg_match_all('/~~(.*?)~~/', $str, $matches);
The code...
<?php
$str="~~I-d0n't-us3-pr0p3r-ch#r#ct3r5~~";
preg_match_all('/~~(.*?)~~/', $str, $matches);
print_r($matches[1]);
OUTPUT :
Array
(
[0] => I-d0n't-us3-pr0p3r-ch#r#ct3r5
)
This should work, but usernames mustn't contain ~~
preg_match_all('!~~(.*?)~~!', $str, $matches);
Output:
Array
(
[0] => Array
(
[0] => ~~timtj~~
[1] => ~~foobar~~
[2] => ~~totallylongusername~~
[3] => ~~I-d0n't-us3-pr0p3r-ch#r#ct3r5~~
)
[1] => Array
(
[0] => timtj
[1] => foobar
[2] => totallylongusername
[3] => I-d0n't-us3-pr0p3r-ch#r#ct3r5
)
)
The first sub array contains the complete matched strings and the other sub arrays contain the matched groups.
You could change the order by using the flag PREG_SET_ORDER, see http://php.net/preg_match_all#refsect1-function.preg-match-all-parameters
<?php
$str = "~~timtj~~ ~~foobar~~ ~~totallylongusername~~ ~~I-d0n't-us3-pr0p3r-ch#r#ct3r5~~";
preg_match_all("!~~(.*?)~~!", str, $matches, PREG_SET_ORDER);
print_r($matches);
This code produces the following output
Array
(
[0] => Array
(
[0] => ~~timtj~~
[1] => timtj
)
[1] => Array
(
[0] => ~~foobar~~
[1] => foobar
)
[2] => Array
(
[0] => ~~totallylongusername~~
[1] => totallylongusername
)
[3] => Array
(
[0] => ~~I-d0n't-us3-pr0p3r-ch#r#ct3r5~~
[1] => I-d0n't-us3-pr0p3r-ch#r#ct3r5
)
)

php separate string by capitals

I have for example this string: "iCanSeeBluePeople" and I need it to separate it into array by capital letters and the first word which starts with lowercase so I would recieve array like ["i","Can","See","Blue","People"]
The strings can be like "grandPrix2009" => ["grand","Prix","2009"], "dog" => ["dog"], "aDog" => ["a","Dog"] and so on
I found this code which works fine but I doesn't apply to numbers and ignores the fist lowercase letter:
<?
$str="MustangBlueHeadlining";
preg_match_all('/[A-Z][^A-Z]*/',$str,$results);
?>
Thanks for help
You can use the regex /[a-z]+|[A-Z]+[a-z]*|[0-9]+/.
<?
$str="thisIsATestVariableNumber000";
preg_match_all('/[a-z]+|[A-Z]+[a-z]*|[0-9]+/',$str,$results);
print_r($results);
?>
Result:
Array
(
[0] => Array
(
[0] => this
[1] => Is
[2] => ATest
[3] => Variable
[4] => Number
[5] => 000
)
)
Use /[a-z]+|[A-Z][a-z]*|[0-9]+/ if you want ATest to be separated into A and Test.
<?
$str="thisIsATestVariableNumber000";
preg_match_all('/[a-z]+|[A-Z][a-z]*|[0-9]+/',$str,$results);
print_r($results);
?>
Result:
Array
(
[0] => Array
(
[0] => this
[1] => Is
[2] => A
[3] => Test
[4] => Variable
[5] => Number
[6] => 000
)
)

What is the regex for the text between quotes?

Ok, I have tried looking at other answers, but couldn't get mine solved. So here is the code:
{"chg":"-0.71","vol":"40700","time":"11.08.2011 12:29:09","high":"1.417","low":"1.360","last":"1.400","pcl":"1.410","turnover":"56,560.25"}
I need to get every second value in the quotes (as the "name" values are constant). I actually worked out that I need to get text between :" and " but i can't manage to write a regex for that.
EDIT: I'm doing preg_match_all in php. And its between :" and ", not " and " as someone else edited.
Why on earth would you attempt to parse JSON with regular expressions? PHP already parses JSON properly, with built-in functionality.
Code:
<?php
$input = '{"chg":"-0.71","vol":"40700","time":"11.08.2011 12:29:09","high":"1.417","low":"1.360","last":"1.400","pcl":"1.410","turnover":"56,560.25"}';
print_r(json_decode($input, true));
?>
Output:
Array
(
[chg] => -0.71
[vol] => 40700
[time] => 11.08.2011 12:29:09
[high] => 1.417
[low] => 1.360
[last] => 1.400
[pcl] => 1.410
[turnover] => 56,560.25
)
Live demo.
You may need to escape characters or add a forward slash to the front or back depending on your language. But it's basically:
:"([^"].*?)"
or
/:"([^"].*?)"/
I've test this in groovy as below and it works.
import java.util.regex.*;
String test='{"chg":"-0.71","vol":"40700","time":"11.08.2011 12:29:09","high":"1.417","low":"1.360","last":"1.400","pcl":"1.410","turnover":"56,560.25"}'
// Create a pattern to match breaks
Pattern p = Pattern.compile(':"([^"]*)"');
// Split input with the pattern
// Run some matches
Matcher m = p.matcher(test);
while (m.find())
System.out.println("Found comment: "+m.group().replace('"','').replace(":",""));
Output was:
Found comment: -0.71
Found comment: 40700
Found comment: 11.08.2011 12:29:09
Found comment: 1.417
Found comment: 1.360
Found comment: 1.400
Found comment: 1.410
Found comment: 56,560.25
PHP Example
<?php
$subject = '{"chg":"-0.71","vol":"40700","time":"11.08.2011 12:29:09","high":"1.417","low":"1.360","last":"1.400","pcl":"1.410","turnover":"56,560.25"}';
$pattern = '/(?<=:")[^"]*/';
preg_match_all($pattern, $subject, $matches, PREG_OFFSET_CAPTURE);
print_r($matches);
?>
Output is:
Array ( [0] => Array ( [0] => Array ( [0] => -0.71 [1] => 8 ) [1] => Array ( [0] => 40700 [1] => 22 ) [2] => Array ( [0] => 11.08.2011 12:29:09 [1] => 37 ) [3] => Array ( [0] => 1.417 [1] => 66 ) [4] => Array ( [0] => 1.360 [1] => 80 ) [5] => Array ( [0] => 1.400 [1] => 95 ) [6] => Array ( [0] => 1.410 [1] => 109 ) [7] => Array ( [0] => 56,560.25 [1] => 128 ) ) )

Categories