Kinda of a noobie in PHP and Regex, I receive the following from a web service:
test:002005#1111#333333#;10205#2000#666666#;002005#1111#55555#;
The above line is a sequence of 3 numbers which repeats 3 times. I would like to get the 3rd number of each sequence and I believe the best course (besides 3000 explodes) would be preg_match_all but I am having a tough time wrapping my mind around RegEx.
The end result should look like this:
Array
(
[0] => 333333
[1] => 666666
[2] => 55555
)
Thanks in advance for any help.
if(preg_match_all('/.*?(?:\d+#){2}(\d+)#;/',$s,$m)) {
print_r($m[1]);
}
http://ideone.com/99M9t
or
You can do it using explode as:
$input = rtrim($input,';');
$temp1 = explode(';',$input);
foreach($temp1 as $val1) {
$temp2 = explode('#',$val1);
$result[] = $temp2[2];
}
print_r($result);
http://ideone.com/VH29g
Use the function explode()
<?php
$pizza = "piece1#piece2#piece3#piece4#piece5#piece6";
$pieces = explode("#", $pizza);
echo $pieces[0]; // piece1
echo $pieces[1]; // piece2
?>
I don't remember exactly how the saying goes but...
"You have a problem and decide to use regular expressions... now you have two problems."
Your problem can easily be solved if we assume 'test:' isn't part of the actual string to be parsed.
<?php
$in = '002005#1111#333333#;10205#2000#666666#;002005#1111#55555#;';
function splitGroupsAndGetColumn($input, $groupSeparator, $columnSeparator, $columnIndex, $skipEmpty=true)
{
$result = array();
$groups = explode($groupSeparator, $input);
foreach($groups as $group)
{
$columns = explode($columnSeparator, $group);
if (isset($columns[$columnIndex]))
{
array_push($result, $columns[$columnIndex]);
}
else if (! $skipEmpty)
{
array_push($result, NULL);
}
}
return $result;
}
var_dump(splitGroupsAndGetColumn($in, ';', '#', 2));
Output:
array(3) {
[0]=>
string(6) "333333"
[1]=>
string(6) "666666"
[2]=>
string(5) "55555"
}
You could use preg_match_all for this task, which makes the task quite simple:
$a = "test:002005#1111#333333#;10205#2000#666666#;002005#1111#55555#;";
preg_match_all('/#(\d+)#;/', $a, $m);
print_r($m);
$m[1] contains the output, you want.
Reference: http://php.net/manual/en/function.preg-match-all.php
My version :)
The regex (\d+) means I want all that is a number one or more
php > $a = '002005#1111#333333#;10205#2000#666666#;002005#1111#55555#';
php > preg_match_all('/(\d+)/',$a,$matches);
php > var_dump($matches);
array(2) {
[0]=>
array(9) {
[0]=>
string(6) "002005"
[1]=>
string(4) "1111"
[2]=>
string(6) "333333"
[3]=>
string(5) "10205"
[4]=>
string(4) "2000"
[5]=>
string(6) "666666"
[6]=>
string(6) "002005"
[7]=>
string(4) "1111"
[8]=>
string(5) "55555"
}
[1]=>
array(9) {
[0]=>
string(6) "002005"
[1]=>
string(4) "1111"
[2]=>
string(6) "333333"
[3]=>
string(5) "10205"
[4]=>
string(4) "2000"
[5]=>
string(6) "666666"
[6]=>
string(6) "002005"
[7]=>
string(4) "1111"
[8]=>
string(5) "55555"
}
}
Related
I'm trying to convert a string into a multidimentional array.
I've found many answers online but they expect you to have array keys etc...
My String:
UserIds\n234234\n20053\n19928\n16325
I've tried the usual way:
$arr= array();
$arr = explode("\n", $string);
and i've also tried
$arr[] = explode("\n", $string);
but the result is always like this:
array(5) {
[0]=> string(7) "UserIds"
[1]=> string(6) "234234"
[2]=> string(5) "20053"
[3]=> string(5) "19928"
[4]=> string(5) "16325"
}
My Expected Result:
array(5) {
[0]=> array(1) { [0]=> string(7) "UserIds" }
[1]=> array(1) { [0]=> int(234234) }
[2]=> array(1) { [0]=> int(20053) }
[3]=> array(1) { [0]=> int(19928) }
[4]=> array(1) { [0]=> int(16325) }
}
One way to do it could be to map the response using array_map and wrap the items in an array:
$string = "UserIds\n234234\n20053\n19928\n16325";
$arr = array_map(function($x){return [$x];}, explode("\n", $string));
print_r($arr);
Demo
Imagine I have a certain text file like this:-
52 apple, one and teen, 682
How to do I take them like this?
$a['aa']['a1'] - 52
$a['aa']['a2'] - apple
$a['bb']['b1'] - one
$a['bb']['b2'] - and
$a['bb']['b3'] - teen
$a['cc']['c1'] - 682
This reads lines from a file, splits them by comma+space and splits each of those by a space:
<?php
$lines = file($filename);
$foo = array_map(
function($v) {
return array_map(
function($u) {
return explode(" ", $u);
},
explode(", ", trim($v))
);
},
$lines
);
var_dump($foo);
Result:
array(1) {
[0]=>
array(3) {
[0]=>
array(2) {
[0]=>
string(2) "52"
[1]=>
string(5) "apple"
}
[1]=>
array(3) {
[0]=>
string(3) "one"
[1]=>
string(3) "and"
[2]=>
string(4) "teen"
}
[2]=>
array(1) {
[0]=>
string(3) "682"
}
}
}
If you really need specific indices you could handle those in the anonymous functions for each array_map on your own. Right now they're just numerically indexed.
Given:
$val = "font-size:12px;color:#ff0000;font-family:Arial";
The following code will explode the string twice, to produce an array of arrays:
$val = explode(';',$val);
foreach($val as &$v)
$v = explode(':',$v);
var_dump($val);
The output is:
array(3) {
[0]=>
array(2) {
[0]=>
string(9) "font-size"
[1]=>
string(4) "12px"
}
[1]=>
array(2) {
[0]=>
string(4) "fill"
[1]=>
string(7) "#ff0000"
}
[2]=>
&array(2) {
[0]=>
string(11) "font-family"
[1]=>
string(5) "Arial"
}
}
Is there a more efficient / cleaner way to achieve the same result?
I'd prefer something with no lambda functions since PHP 5.2 doesn't support them. But this is a purely intellectual question anyway, so, that's just a preference.
You can try with:
$input = "font-size:12px;color:#ff0000;font-family:Arial";
preg_match_all('/([^:]*?):([^;]*);?/', $input, $matches);
$output = array_combine($matches[1], $matches[2]);
Output:
array(3) {
["font-size"]=>
string(4) "12px"
["color"]=>
string(7) "#ff0000"
["font-family"]=>
string(5) "Arial"
}
I'd recommend against references--you can run into some odd errors. But your approach is fine. Alternatively, you could do something with array_map:
$val = array_map(function($v) { return explode(':', $v); }, explode(';', $val)));
I'm planning to build web app and i heve question how to create mentions for name "#myname" like facebook or twitter
Find them in a string with this regex....
$str = 'Yo #bob, what\'s up? I have a new email, tom#bob.com, tell #john too, from #alex';
preg_match_all('/\s#(?P<mention>\w+?)\b/', $str, $mentions);
var_dump($mentions);
Output
array(3) {
[0]=>
array(3) {
[0]=>
string(5) " #bob"
[1]=>
string(6) " #john"
[2]=>
string(6) " #alex"
}
["mention"]=>
array(3) {
[0]=>
string(3) "bob"
[1]=>
string(4) "john"
[2]=>
string(4) "alex"
}
[1]=>
array(3) {
[0]=>
string(3) "bob"
[1]=>
string(4) "john"
[2]=>
string(4) "alex"
}
}
Of course, you could real time detect them in a string in JavaScript, just change that regex to a JavaScript one.
Then, you would look up your database based on the tagged name, and then do what you need to do!
You could cut down on requests by limiting your regex to what makes a valid username, e.g. /\w{6,}/.
function mention($txt)
{
$txt = ' '.$txt;
preg_match_all('/\s#(?P<mention>\w+?)\b/', $txt, $mentions);
echo "<pre>";
print_r($mentions);
if (isset($mentions[0])) {
foreach ($mentions[0] as $key => $value) {
$mention = strtolower(str_replace(array("#"," "), "", $value));
$txt = str_replace($value, ' '.$mention.'', $txt);
}
}
return trim($txt);
}
I'm trying to extract some specific pictures from html content . Currently I have the following array
[1] => Array
(
[0] => BuEZm5g!Wk~$(KGrHqQH-DgEvrb2CLuOBL-vbkHlKw~~_14.JPG#!BuEZm5g!Wk~$(KGrHqQH-DgEvrb2CLuOBL-vbkHlKw~~_12.JPG|1#http://i.ebayimg.com/08#!BuEZqMQBGk~$(KGrHqQH-DoEvrKYSoPiBL-vb)WgLw~~_14.JPG#!BuEZqMQBGk~$(KGrHqQH-DoEvrKYSoPiBL-vb)WgLw~~_12.JPG|2#http://i.ebayimg.com/13#!BuEZtkw!2k~$(KGrHqYH-EYEvsh4EjJSBL-vb-bLow~~_14.JPG#!BuEZtkw!2k~$(KGrHqYH-EYEvsh4EjJSBL-vb-bLow~~_12.JPG|3#http://i.ebayimg.com/03#!BuEZ)!wEGk~$(KGrHqYH-DwEvq8Z1JuQBL-vcMOoFQ~~_14.JPG#!BuEZ)!wEGk~$(KGrHqYH-DwEvq8Z1JuQBL-vcMOoFQ~~_12.JPG|4#http://i.ebayimg.com/09#!BuEZ1IQEGk~$(KGrHqEH-D0EvqwClvviBL-vcclJwg~~_14.JPG#!BuEZ1IQEGk~$(KGrHqEH-D0EvqwClvviBL-vcclJwg~~_12.JPG|5#http://i.ebayimg.com/17#!BuEZ4FQCWk~$(KGrHqUH-DMEvS+,FRj5BL-vco)Qgg~~_14.JPG#!BuEZ4FQCWk~$(KGrHqUH-DMEvS+,FRj5BL-vco)Qgg~~_12.JPG|6#http://i.ebayimg.com/17#!BuEZ7FQEWk~$(KGrHqYH-EYEvsh4EjJSBL-vc1v2Hg~~_14.JPG#!BuEZ7FQEWk~$(KGrHqYH-EYEvsh4EjJSBL-vc1v2Hg~~_12.JPG|7#http://i.ebayimg.com/12#!BuEZ-c!Bmk~$(KGrHqQH-CYEvr5z9)NVBL-vdC,)Mg~~_14.JPG#!BuEZ-c!Bmk~$(KGrHqQH-CYEvr5z9)NVBL-vdC,)Mg~~_12.JPG|8#http://i.ebayimg.com/20#!BuE,CNgCWk~$(KGrHqIH-CIEvqKBurmhBL-vdRBe3!~~_14.JPG#!BuE,CNgCWk~$(KGrHqIH-CIEvqKBurmhBL-vdRBe3!~~_12.JPG|9#http://i.ebayimg.com/24#!BuE,FN!EWk~$(KGrHqUH-C0EvsBdjbv0BL-vdeFkD!~~_14.JPG#!BuE,FN!EWk~$(KGrHqUH-C0EvsBdjbv0BL-vdeFkD!~~_12.JPG|10#http://i.ebayimg.com/16#!BuE,IOgBmk~$(KGrHqEH-EMEvpym7mSLBL-vdqI6nw~~_14.JPG#!BuE,IOgBmk~$(KGrHqEH-EMEvpym7mSLBL-vdqI6nw~~
)
I need to extract only the pictures that start with ! and ends in 12.JPG . An example of expected result is
!BuEZm5g!Wk~$(KGrHqQH-DgEvrb2CLuOBL-vbkHlKw~~_12.JPG
. I have a pattern but it doesn't work for some reasons that I don't know . It is
$pattern = "/#\!(.*)_12.JPG/";
Thank you in advance for any help
Not a regex problem.
$names = explode('#', $names);
$keep = array();
foreach ($names as $name)
{
if ((substr($name, 0, 1) == '!') && (substr($name, -6) == '12.JPG'))
{
$keep[] = $name;
}
}
Try using '/#\!([^_]+)_12.JPG/' instead. Also, you're using preg_match_all, right?
Example ..
<?php
$input = '(that long string you have)';
$matches = array();
preg_match_all('/#\!([^_]+)_12.JPG/', $input, $matches);
var_dump($matches);
Output (notice how $matches[0] contains all full matches, and $matches[1] contains all grouped (up to _12.JPG) matches) ..
array(2) {
[0]=>
array(10) {
[0]=>
string(53) "#!BuEZm5g!Wk~$(KGrHqQH-DgEvrb2CLuOBL-vbkHlKw~~_12.JPG"
[1]=>
string(53) "#!BuEZqMQBGk~$(KGrHqQH-DoEvrKYSoPiBL-vb)WgLw~~_12.JPG"
[2]=>
string(53) "#!BuEZtkw!2k~$(KGrHqYH-EYEvsh4EjJSBL-vb-bLow~~_12.JPG"
[3]=>
string(53) "#!BuEZ)!wEGk~$(KGrHqYH-DwEvq8Z1JuQBL-vcMOoFQ~~_12.JPG"
[4]=>
string(53) "#!BuEZ1IQEGk~$(KGrHqEH-D0EvqwClvviBL-vcclJwg~~_12.JPG"
[5]=>
string(53) "#!BuEZ4FQCWk~$(KGrHqUH-DMEvS+,FRj5BL-vco)Qgg~~_12.JPG"
[6]=>
string(53) "#!BuEZ7FQEWk~$(KGrHqYH-EYEvsh4EjJSBL-vc1v2Hg~~_12.JPG"
[7]=>
string(53) "#!BuEZ-c!Bmk~$(KGrHqQH-CYEvr5z9)NVBL-vdC,)Mg~~_12.JPG"
[8]=>
string(53) "#!BuE,CNgCWk~$(KGrHqIH-CIEvqKBurmhBL-vdRBe3!~~_12.JPG"
[9]=>
string(53) "#!BuE,FN!EWk~$(KGrHqUH-C0EvsBdjbv0BL-vdeFkD!~~_12.JPG"
}
[1]=>
array(10) {
[0]=>
string(44) "BuEZm5g!Wk~$(KGrHqQH-DgEvrb2CLuOBL-vbkHlKw~~"
[1]=>
string(44) "BuEZqMQBGk~$(KGrHqQH-DoEvrKYSoPiBL-vb)WgLw~~"
[2]=>
string(44) "BuEZtkw!2k~$(KGrHqYH-EYEvsh4EjJSBL-vb-bLow~~"
[3]=>
string(44) "BuEZ)!wEGk~$(KGrHqYH-DwEvq8Z1JuQBL-vcMOoFQ~~"
[4]=>
string(44) "BuEZ1IQEGk~$(KGrHqEH-D0EvqwClvviBL-vcclJwg~~"
[5]=>
string(44) "BuEZ4FQCWk~$(KGrHqUH-DMEvS+,FRj5BL-vco)Qgg~~"
[6]=>
string(44) "BuEZ7FQEWk~$(KGrHqYH-EYEvsh4EjJSBL-vc1v2Hg~~"
[7]=>
string(44) "BuEZ-c!Bmk~$(KGrHqQH-CYEvr5z9)NVBL-vdC,)Mg~~"
[8]=>
string(44) "BuE,CNgCWk~$(KGrHqIH-CIEvqKBurmhBL-vdRBe3!~~"
[9]=>
string(44) "BuE,FN!EWk~$(KGrHqUH-C0EvsBdjbv0BL-vdeFkD!~~"
}
}