-2

If I have a string like this:

$string = "number: 20 (10 30 10 zzz) 40 60";

How do I match all numbers outside the parentheses?

I would like to get only

20,40,60
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
SahebSoft
  • 31
  • 7
  • I will give you a hint. Replace stuff inside `()` with blank and then match remaining digits. – Rahul May 25 '17 at 18:12
  • Quick and dirty you could explode(" ",$string); and just grab positions 0, 5 and 6 – clearshot66 May 25 '17 at 18:12
  • 2
    You could skip them if the parenthesis are always matching, `\([^)]+\)(*SKIP)(*FAIL)|\d+`. – chris85 May 25 '17 at 18:13
  • You could solve this in a myriad of ways, however remember that regex can not match balanced parentheses as described [here](https://stackoverflow.com/questions/133601/can-regular-expressions-be-used-to-match-nested-patterns). So unless you wont ever have more than one set of parentheses, you should reconsider your approach. – Olian04 May 25 '17 at 18:22
  • 1
    Regular Expressions in practice differs from theories. If you were familiar with recursions then you'd know it's possible in PCRE. @Olian04 – revo May 25 '17 at 19:23
  • @revo I'm aware that some regex implementations do support feature outside the core 'regular expressions' definition. However 'regular expression' can not match balanced parentheses. (I should also mention that i haven't used PCRE) – Olian04 May 25 '17 at 19:27
  • Since OP struggles with the problem in a programming language scope, Regular Expressions in theories doesn't apply much. `php` uses `PCRE`, the most well-featured regex engine, in order to work with them which out of the box supports recursions as well. @Olian04 – revo May 25 '17 at 19:36
  • @revo As i said, i havent used PCRE. But thank you for the clarification. The more you know :) – Olian04 May 25 '17 at 19:37
  • You only need to get the first sentence of last comment of mine. No problem with not being familiar with `PCRE` at all. @Olian04 – revo May 25 '17 at 19:39

1 Answers1

1

Here is a preg_split() approach:

Input:

$string = "number: 20 (10 30 10 zzz) 40 60";

One-liner (Pattern Demo):

var_export(preg_split('/ |number: |\([^)]*\)/', $string, 0, PREG_SPLIT_NO_EMPTY));

Output:

array (
  0 => '20',
  1 => '40',
  2 => '60',
)

This pattern will explode on:

  • every space
  • every number:
  • every parenthetical expression

Edits:

This pattern also works with preg_split(): /[ a-z:]+|\([^)]*\)/i It is slightly faster.

...

chris85's commented pattern for preg_match() is correct. I have optimized it by reversing the alternatives: \d+|\([^)]+\)(*SKIP)(*FAIL)

mickmackusa
  • 43,625
  • 12
  • 83
  • 136