0

I have a string of the format:

$15?1?2/:1$16E/:2$17?6?7/:6$19E/:7$3E/

I want to use preg_split() to break this down into an array but I can't seem to get the regex right. Specifically I want to get an array with all the numerical values directly following each $.

So in this case:

[0] => 15
[1] => 16
[2] => 17
[3] => 19
[4] => 3 

If someone could explain the regex to me that would produce this that would be amazing.

ajax1515
  • 190
  • 1
  • 13

3 Answers3

1

Split vs. Match All

Splitting and matching are two sides of the same coin. You don't even need to split: this returns the exact array you are looking for (see PHP demo).

$regex = '~\$\K\d+~';
$count = preg_match_all($regex, $yourstring, $matches);
print_r($matches[0]);

Output

Array
(
    [0] => 15
    [1] => 16
    [2] => 17
    [3] => 19
    [4] => 3
)

Explanation

  • \$ matches a $
  • The \K tells the engine to drop what was matched so far from the final match it returns
  • \d+ matches your digits

Hang tight for explanation. :)

zx81
  • 41,100
  • 9
  • 89
  • 105
  • Do you have an [advice on this one](http://stackoverflow.com/questions/24541489/crontab-intervals-preg-match) too, maybe? – Daniel W. Jul 02 '14 at 22:08
  • @DanFromGermany Would love to help on your question, but not fully understanding the format. One example is not enough. @ me on your question if you add sample input. – zx81 Jul 02 '14 at 22:37
  • Worked perfectly, easy to change to fit a variety of different strings now that *I think* I understand the format. Thank you so much zx81 – ajax1515 Jul 03 '14 at 15:37
0

Or this:

$preg = preg_match_all("/\$(\d+)/", $input, $output);
print_r($output[1]);

http://www.phpliveregex.com/p/5Rc

Daniel W.
  • 31,164
  • 13
  • 93
  • 151
0

Here is non-regular expression example:

$string = '$15?1?2/:1$16E/:2$17?6?7/:6$19E/:7$3E/';

$array = array_map( function( $item ) {
    return intval( $item );
}, array_filter( explode( '$', $string ) ) );

Idea is to explode the string by $ character, and to map that array and use the intval() to get the integer value.


Here is preg_split() example that captures the delimiter:

$string = '$15?1?2/:1$16E/:2$17?6?7/:6$19E/:7$3';

$array = preg_split( '/(?<=\$)(\d+)(?=\D|$)/', $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE );
/*
  (?<=\$)                  look behind to see if there is: '$'
  (                        group and capture to \1:
    \d+                      digits (0-9) (1 or more times (greedy))
  )                        end of \1
  (?=\D|$)                 look ahead to see if there is: non-digit (all but 0-9) OR the end of the string
*/

With a help of this post, a interesting way to get every second value from resulting array.

$array = array_intersect_key( $array, array_flip( range( 1, count( $array ), 2 ) ) );
Community
  • 1
  • 1
Danijel
  • 12,408
  • 5
  • 38
  • 54