1

I want to split '9088{2}12{1}729' into [ "9088", "{2}12", "{1}729" ]

or even more useful to me: [ "9088", "2-12", "1-729" ]

tried:

'9088{2}12{1}729'.split(/\{[0-9]+\}/); => ["9088", "12", "729"]

also tried:

'9088{2}12{1}729'.match(/\{[0-9]+\}/); => ["{2}"]

I know it probably involved some other regexp string to split including delimiters.


Tried it in php, I guess you can do it in one line also.

preg_split( '/{/', preg_replace( '/}/', '-', "9088{2}12{1}729" ) )

Array ( [0] => 9088 [1] => 2-12 [2] => 1-729 )

Just have to wrap the replace function with split to get the preference order correct.

I think I like js more :)

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
Bruce Lim
  • 745
  • 6
  • 22

2 Answers2

4

even more useful to me: [ "9088", "2-12", "1-729" ]

It can be done using simple tricks!

"9088{2}12{1}729".replace(/\}/g,'-').split(/\{/g)

// ["9088", "2-12", "1-729"]
Shiplu Mokaddim
  • 56,364
  • 17
  • 141
  • 187
2

You can use a simple zero-width positive lookahead with /(?={)/:

'9088{2}12{1}729'.split(/(?=\{)/);  // => ["9088","{2}12","{1}729"]

The "zero-width" part means that the actual matched text is the empty string so the split throws away nothing, and the lookahead means it matches just before the contained pattern, so /(?=\{)/ matches the empty strings between characters where indicated by an arrow:

9 0 8 8 { 2 } 1 2 { 1 } 7 2 9
       ↑         ↑

You can then use Array.prototype.map to convert from {1}2 form to 1-2 form.

'9088{2}12{1}729'.split(/(?=\{)/)
    .map(function (x) { return x.replace('{', '').replace('}', '-'); });

yields

["9088","2-12","1-729"]
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245