2
array (    
    [0] => 3 / 4 Bananas
    [1] => 1 / 7 Apples
    [2] => 3 / 3 Kiwis
    )

Is it possible, to say, iterate through this list, and explode between the first letter and first integer found, so I could seperate the text from the set of numbers and end up with something like:

array (
   [0] => Bananas
   [1] => Apples
   [2] => Kiwis
   )

I have no idea how you would specify this as the delimiter. Is it even possible?

foreach ($fruit_array as $line) {
   $var = explode("??", $line);
}

Edit: updated example. exploding by a space wouldn't work. see above example.

1
  • what is the format of the list, is it a string or array? Commented Sep 14, 2012 at 23:21

5 Answers 5

6

You could use preg_match instead of explode:

$fruit_array = array("3 / 4 Bananas", "1 / 7 Apples", "3 / 3 Kiwis");
$result = array();
foreach ($fruit_array as $line) {
   preg_match("/\d[^A-Za-z]+([A-Za-z\s]+)/", $line, $match);
   array_push($result, $match[1]);
}

It will almost literally match your expression, that is, a digit \d, followed by one or more non-letters [^A-Za-z], followed by one or more letters or whitespace (to account for multiple words) [A-Za-z\s]+. This final matched string, between parentheses, will be captured in the first match, i.e., $match[1].

Here's a DEMO.

Sign up to request clarification or add additional context in comments.

2 Comments

What if the fruit name had two words, like Green Apples? Your example would match just Green
@Norse: Just add an extra \s to [A-Za-z] to match whitespaces. This way, it also matches multiple words. I've edited my answer and my demo.
3

You could also use the PREG_OFFSET_CAPTURE flag in preg_match:

$a = array('1/4 banana', '3/5 apple', '3/2 peach');

foreach ($a as $b) {
    preg_match('/[a-z]/', $b, $matches, PREG_OFFSET_CAPTURE);
    $pos = $matches[0][1]; // position of first match of [a-z] in each case
    $c[] = substr($b, $pos);  
}

print_r($c);


Array ( [0] => banana [1] => apple [2] => peach )

Comments

3
// An array to hold the result
$result = array();

// Loop the input array
foreach ($array as $str) {

  // Split the string to a maximum of 2 parts
  // See below for regex description
  $parts = preg_split('/\d\s*(?=[a-z])/i', $str, 2);

  // Push the last part of the split string onto the result array
  $result[] = array_pop($parts);

}

// Display the result
print_r($result);

The regex works like this:

/
  # Match any digit
  \d
  # Match 0 or more whitespace characters
  \s*
  # Assert that the next character is a letter without including it in the delimiter
  (?=[a-z])
/i

See it working

Comments

3

If you want to explode "between the first letter and the first integer found" you shouldn't use explode.

The PHP explode function accepts a delimiter as its first argument:

array explode ( string $delimiter , string $string [, int $limit ] )

That means it's not "smart" enough to understand a complicated rule like "between the first letter and the first integer found" - it only understands things like "split on '1'" or "split on 'A'". The delimiter has to be something concrete: a specific letter and a specific integer, for example. (ie "between the letter 'B' and the integer '4'")

For something more abstract/general, like what you described ("between the first letter and the first integer found") you will need a pattern. So the best bet is to use preg_replace or preg_split instead, like so:

<?php

$myArr = [    
    "3 / 4 Bananas",
    "1 / 7 Apples",
    "3 / 3 Kiwis",
    "1 / 7 Green Apples",
];

for($i=0; $i<count($myArr); $i++) {
    echo "<pre>";
    echo preg_replace("/^.*?\d[^\d[a-z]]*([a-z])/i", "$1", $myArr[$i]);
    echo "</pre>";
}

?>

Comments

0

Something like this:

foreach ($fruit_array as $line) {
   $var = explode(" ", $line);
   $arr[$var[2]] = $var[3];
}

var_dump( $arr ) should output:

array (
   [0] => Bananas
   [1] => Apples
   [2] => Kiwis
   )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.