PHP using explode - php

I'm trying to explode and separate the results in 2 different arrays
One One_x
Two Two_xx
Three Three_xxx
Four Four_xxxx
I first want to explode the break line ( \n )..
then explode the space to come up with all One, Two, Three, Four in an array
AND One_x, Two_xx, Three_xxx, Four_xxxx in a different array
i tried to explode the break line
$ex = explode("\n", $numbers);
then
foreach($ex as $number){
$ex = explode(" ", $number);
}
but it seems a bit confusing to me,
How to solve this ?

$array1 = array();
$array2 = array();
foreach($ex as $number){
$tmp = explode(" ", $number);
$array1[] = $tmp[0];
$array2[] = $tmp[1];
}
Simplest way I think
EDIT: care you set $ex in loop ... Not a good idea. Use another var

Instead of runnig explode once or twice, a regex can split up the input at once, and assert the structure at it:
preg_match_all('/
^ # line start
(\w+) # One, Two, ...
\s+ # spaces
(\w+) # Four_xxxxx
$ # line end
/smix',
$input,
$array
);
print_r($array);
Will give you:
[0] => Array
(
[0] => One One_x
[1] => Two Two_xx
[2] => Three Three_xxx
[3] => Four Four_xxxx
)
[1] => Array
(
[0] => One
[1] => Two
[2] => Three
[3] => Four
)
[2] => Array
(
[0] => One_x
[1] => Two_xx
[2] => Three_xxx
[3] => Four_xxxx
)
One could also use PREG_SET_ORDER or even extract the trailing _xxxx (?)numbers.

Related

Remove last character from string if last character contain number in PHP

I have an array variable which contain values like this:
$items = array(
"tbFrench",
"eaItaly1",
"discount21",
"kkMM5",
"NbndA",
"fcMNSS334"
);
i nedd to remove last character of string from this array values if the last character contain number, for example:
$newItems = array();
foreach($items as $item){
$newItems[] = $this->removeLastCharacter($item);
}
print_r($newItems);
....
function removeLastCharacter($string){
// ????
}
i want the result to look like this when i print_r the $newItems variable:
Array ( [0] => tbFrench [1] => eaItaly [2] => discount2 [3] => kkMM [4] => NbndA [5] => fcMNSS33 )
You could use regular expressions to remove the last digit.
function removeLastCharacter($string){
return preg_replace('[\d$]', '', $string);
}
\d matches every digit and $ references the end of the string. So this will only replace the last character if it is a digit at the end.
You can do a RegEx replacement over all the items in an array by simply providing the array as the subject, like so:
$items = preg_replace('/^d$/', '', $items);
There's no need to put it into a function at all - print_r($items) outputs:
Array
(
[0] => tbFrench
[1] => eaItaly
[2] => discount2
[3] => kkMM
[4] => NbndA
[5] => fcMNSS33
)
If you want to replace all trailing digits you can use /^\d+$/
Give a try with below code if it solve your problem
$items = array(
"tbFrench",
"eaItaly1",
"discount21",
"kkMM5",
"NbndA",
"fcMNSS334"
);
$newArr=array();
foreach($items as $item){
$data = preg_replace('[\d$]','',$item);
array_push($newArr,$data);
}
print_r($newArr);
Why not simply?
print_r( preg_replace( '/\d+$/', "", $items ) ); // preg_replace accepts an array as argument, pass yours directly, no need for a loop.
Array
(
[0] => tbFrench
[1] => eaItaly
[2] => discount
[3] => kkMM
[4] => NbndA
[5] => fcMNSS
)
Regex Explanation:
\d+ — matches a digit (equal to [0-9])
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
$ — asserts position at the end of a line
There is a quick trick using rtrim.
$result = rtrim($str,"0..9");
second argument is a range using 2 dots ".."
You are done !!!

Most elegant way to clean a string into only comma separated numerals

After instructing clients to input only
number comma number comma number
(no set length, but generally < 10), the results of their input have been, erm, unpredictable.
Given the following example input:
3,6 ,bannana,5,,*,
How could I most simply, and reliably end up with:
3,6,5
So far I am trying a combination:
$test= trim($test,","); //Remove any leading or trailing commas
$test= preg_replace('/\s+/', '', $test);; //Remove any whitespace
$test= preg_replace("/[^0-9]/", ",", $test); //Replace any non-number with a comma
But before I keep throwing things at it...is there an elegant way, probably from a regex boffin!
In a purely abstract sense this is what I'd do:
$test = array_filter(array_map('trim',explode(",",$test)),'is_numeric')
Example:
http://sandbox.onlinephpfunctions.com/code/753f4a833e8ff07cd9c7bd780708f7aafd20d01d
<?php
$str = '3,6 ,bannana,5,,*,';
$str = explode(',', $str);
$newArray = array_map(function($val){
return is_numeric(trim($val)) ? trim($val) : '';
}, $str);
print_r(array_filter($newArray)); // <-- this will give you array
echo implode(',',array_filter($newArray)); // <--- this give you string
?>
Here's an example using regex,
$string = '3,6 ,bannana,5,-6,*,';
preg_match_all('#(-?[0-9]+)#',$string,$matches);
print_r($matches);
will output
Array
(
[0] => Array
(
[0] => 3
[1] => 6
[2] => 5
[3] => -6
)
[1] => Array
(
[0] => 3
[1] => 6
[2] => 5
[3] => -6
)
)
Use $matches[0] and you should be on your way.
If you don't need negative numbers just remove the first bit in the in the regex rule.

Convert string to array at different character occurence

Consider I have this string 'aaaabbbaaaaaabbbb' I want to convert this to array so that I get the following result
$array = [
'aaaa',
'bbb',
'aaaaaa',
'bbbb'
]
How to go about this in PHP?
PHP code demo
Regex: (.)\1{1,}
(.): Match and capture single character.
\1: This will contain first match
\1{1,}: Using matched character one or more times.
<?php
ini_set("display_errors", 1);
$string="aaaabbbaaaaaabbbb";
preg_match_all('/(.)\1{1,}/', $string,$matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => aaaa
[1] => bbb
[2] => aaaaaa
[3] => bbbb
)
[1] => Array
(
[0] => a
[1] => b
[2] => a
[3] => b
)
)
Or:
PHP code demo
<?php
$string="aaaabbbaaaaaabbbb";
$array=str_split($string);
$start=0;
$end= strlen($string);
$indexValue=$array[0];
$result=array();
$resultantArray=array();
while($start!=$end)
{
if($indexValue==$array[$start])
{
$result[]=$array[$start];
}
else
{
$resultantArray[]=implode("", $result);
$result=array();
$result[]=$indexValue=$array[$start];
}
$start++;
}
$resultantArray[]=implode("", $result);
print_r($resultantArray);
Output:
Array
(
[0] => aaaa
[1] => bbb
[2] => aaaaaa
[3] => bbbb
)
I have written a one-liner using only preg_split() that generates the expected result with no wasted memory (no array bloat):
Code (Demo):
$string = 'aaaabbbaaaaaabbbb';
var_export(preg_split('/(.)\1*\K/', $string, 0, PREG_SPLIT_NO_EMPTY));
Output:
array (
0 => 'aaaa',
1 => 'bbb',
2 => 'aaaaaa',
3 => 'bbbb',
)
Pattern:
(.) #match any single character
\1* #match the same character zero or more times
\K #keep what is matched so far out of the overall regex match
The real magic happens with the \K, for more reading go here.
The 0 parameter in preg_split() means "unlimited matches". This is the default behavior, but it needs to hold its place in the function so that the next parameter is used appropriately as a flag
The final parameter is PREG_SPLIT_NO_EMPTY which removes any empty matches.
Sahil's preg_match_all() method preg_match_all('/(.)\1{1,}/', $string,$matches); is a good attempt but it is not perfect for two reasons:
The first issue is that his use of preg_match_all() returns two subarrays which is double the necessary result.
The second issue is revealed when $string="abbbaaaaaabbbb";. His method will ignore the first lone character. Here is its output:
Array (
[0] => Array
(
[0] => bbb
[1] => aaaaaa
[2] => bbbb
)
[1] => Array
(
[0] => b
[1] => a
[2] => b
)
)
Sahil's second attempt produces the correct output, but requires much more code. A more concise non-regex solution could look like this:
$array = str_split($string);
$last = "";
foreach ($array as $v) {
if (!$last || strpos($last, $v) !== false) {
$last .= $v;
} else {
$result[] = $last;
$last = $v;
}
}
$result[] = $last;
var_export($result);

Remove spaces from array values

I have a string which contains numbers separated by commas. It may or may not have a space in between the numbers and a comma in the end. I want to convert it into an array, that I can do using following code:
$string = '1, 2,3,';
$array = explode(',', $string);
However the additional irregular spaces gets in the array values and the last comma causes an empty index (see image below).
How can I remove that so that I get only clean values without spaces and last empty index in the array?
Simply use array_map, array_filter and explode like as
$string = '1, 2,3,';
print_r(array_map('trim',array_filter(explode(',',$string))));
Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Explanation:
Firstly I've split string into an array using explode function of PHP
print_r(explode(',',$string));
which results into
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] =>
)
So we need to remove those null values using array_filter like as
print_r(array_filter(explode(',',$string)));
which results into
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Now the final part need to remove that (extra space) from the values using array_map along with trim
print_r(array_map('trim',array_filter(explode(',',$string))));
SO finally we have achieved the part what we're seeking for i.e.
Array
(
[0] => 1
[1] => 2
[2] => 3
)
Demo
The simple solution would be to use str_replace on the original string and also remove the last comma if it exists with a rtrim so you dont get an empty occurance at the end of the array.
$string = '1, 2,3,';
$string = rtrim($string, ',');
$string = str_replace(' ', '', $string);
$array = explode(',', $string);
print_r($array);
RESULT:
Array
(
[0] => 1
[1] => 2
[2] => 3
)
First perform following on the string -
$string = str_replace(' ', '', $string);
Then use explode.
$string = '1, 2,3,';
$array = explode(',', $string);
$array = array_filter(array_map('trim', $array));
print_r($array);
array_map is a very useful function that allows you to apply a method to every element in an array, in this case trim.
array_filter will then handle the empty final element for you.
This will trim each value and remove empty ones in one operation
$array = array_filter( array_map( 'trim', explode( ',', $string ) ) );

Split a single string into an array using specific Regex rules

I'm processing a single string which contains many pairs of data. Each pair is separated by a ; sign. Each pair contains a number and a string, separated by an = sign.
I thought it would be easy to process, but i've found that the string half of the pair can contain the = and ; sign, making simple splitting unreliable.
Here is an example of a problematic string:
123=one; two;45=three=four;6=five;
For this to be processed correctly I need to split it up into an array that looks like this:
'123', 'one; two'
'45', 'three=four'
'6', 'five'
I'm at a bit of dead end so any help is appreciated.
UPDATE:
Thanks to everyone for the help, this is where I am so far:
$input = '123=east; 456=west';
// split matches into array
preg_match_all('~(\d+)=(.*?);(?=\s*(?:\d|$))~', $input, $matches);
$newArray = array();
// extract the relevant data
for ($i = 0; $i < count($matches[2]); $i++) {
$type = $matches[2][$i];
$price = $matches[1][$i];
// add each key-value pair to the new array
$newArray[$i] = array(
'type' => "$type",
'price' => "$price"
);
}
Which outputs
Array
(
[0] => Array
(
[type] => east
[price] => 123
)
)
The second item is missing as it doesn't have a semicolon on the end, i'm not sure how to fix that.
I've now realised that the numeric part of the pair sometimes contains a decimal point, and that the last string pair does not have a semicolon after it. Any hints would be appreciated as i'm not having much luck.
Here is the updated string taking into account the things I missed in my initial question (sorry):
12.30=one; two;45=three=four;600.00=five
You need a look-ahead assertion for this; the look-ahead matches if a ; is followed by a digit or the end of your string:
$s = '12.30=one; two;45=three=four;600.00=five';
preg_match_all('/(\d+(?:.\d+)?)=(.+?)(?=(;\d|$))/', $s, $matches);
print_r(array_combine($matches[1], $matches[2]));
Output:
Array
(
[12.30] => one; two
[45] => three=four
[600.00] => five
)
I think this is the regex you want:
\s*(\d+)\s*=(.*?);(?=\s*(?:\d|$))
The trick is to consider only the semicolon that's followed by a digit as the end of a match. That's what the lookahead at the end is for.
You can see a detailed visualization on www.debuggex.com.
You can use following preg_match_all code to capture that:
$str = '123=one; two;45=three=four;6=five;';
if (preg_match_all('~(\d+)=(.+?);(?=\d|$)~', $str, $arr))
print_r($arr);
Live Demo: http://ideone.com/MG3BaO
$str = '123=one; two;45=three=four;6=five;';
preg_match_all('/(\d+)=([a-zA-z ;=]+)/', $str,$matches);
echo '<pre>';
print_r($matches);
echo '</pre>';
o/p:
Array
(
[0] => Array
(
[0] => 123=one; two;
[1] => 45=three=four;
[2] => 6=five;
)
[1] => Array
(
[0] => 123
[1] => 45
[2] => 6
)
[2] => Array
(
[0] => one; two;
[1] => three=four;
[2] => five;
)
)
then y can combine
echo '<pre>';
print_r(array_combine($matches[1],$matches[2]));
echo '</pre>';
o/p:
Array
(
[123] => one; two;
[45] => three=four;
[6] => five;
)
Try this but this code is written in c#, you can change it into php
string[] res = Regex.Split("123=one; two;45=three=four;6=five;", #";(?=\d)");
--SJ

Categories