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
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 !!!
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.
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);
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 ) ) );
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