2

I have a string like

abc123/xyz456/abc/123/aaa/zzz 

I would like to split it as

abc123,  xyz456 and abc/123/aaa/zzz

Basically, I want to split and get the first 2 items as separate items and the rest of the items can be combined.

I tried the regex ^(.*)\/(.*)\/(.*)$ but it gives me the other way around like zzz, aaa and abc123/xyz456/abc/123.

Is there a way to get this parsed from left to right instead of right to left? or any suggestions would be helpful

imtheman
  • 4,713
  • 1
  • 30
  • 30
user408558
  • 55
  • 1
  • 5

2 Answers2

2

The easiest fix will be to modify the first two .* to .*? to make the first two .* lazy (that is, match up to the first occurrence of the subsequent subpattern):

^(.*?)\/(.*?)\/(.*)$
 ^^^^^^^^^^^

See the regex demo

Else, use negated character class [^\/] that matches any char but /:

^([^\/]*)\/([^\/]*)\/(.*)$

See another demo

Note that * quantifier matches zero or more occurrences of the quantified subpattern, you need to replace it with + (one or more occurrences) if you need to match at least one.

Note that the last .* can remain as is, a greedy pattern, as it is at the pattern end and will match as many chars (other than line break chars) as possible, up to the string end. Turning it to .*? (i.e. .*?$) makes no sense as it will slow down matching.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thanks for the explanation. I still have a question for my own understanding - what does ? do here on the first example? – user408558 Mar 09 '17 at 21:54
  • Lazy version of the `.*` quantifier. The `.*?` matches up to the first occurrence of the subsequent subpattern(s). If `.*` grabs the whole string and then backtracks to accommodate text for the subsequent subpatterns, the lazy pattern is first skipped, and all subsequent subpatterns are tried first. If there is a fail, the lazily quantified pattern is *expanded*, i.e. matches one char if it can, and again the subsequent subpatterns are tried. See [this SO answer](http://stackoverflow.com/a/5319978/3832970). – Wiktor Stribiżew Mar 09 '17 at 21:55
  • 1
    Thanks Wiktor. Appreciate it! – user408558 Mar 10 '17 at 20:14
0

Try the following:

^([^\/]+)\/([^\/]+)\/(.*)$
Jean-Bernard Pellerin
  • 12,556
  • 10
  • 57
  • 79