1

I am trying to parse :hello::world: and grab hello and world individually. Unfortunately the following results in this:

const str = ':hello::world:'
const matches = str.match(/\:[^\s]+\:/g)
console.log(matches) // [':hello::world:']
robinnnnn
  • 1,675
  • 4
  • 17
  • 32

3 Answers3

4

Your regex match any string except space that cause match all of string. So you need match any string except :

const str = ':hello::world:'
const matches = str.match(/[^:]+/g);
console.log(matches); 

Note that you can do this work without regex. Just split string by : delimiter and remove empty items using .filter()

const str = ':hello::world:'
const matches = str.split(':').filter(v=>v!='');
console.log(matches) 
Mohammad
  • 21,175
  • 15
  • 55
  • 84
1

Your specific use case allows a more simple implementation, but being very strict to your question, you can use this regex:

/(?<=:)([^:]+)(?=:)/g

It searches for any non colon text that is preceded and followed by a colon. This way, you can change "str" to "start:hello::brave new world:end" and it still meets your rule in that 'start' and 'end' are excluded because they don't have colons on both sides, and 'brave new world' comes through as a unit.

const str = 'start:hello::brave new world:end';
const matches = str.match(/(?<=:)([^:]+)(?=:)/g);
console.log(matches); // ["hello", "brave new world"]

As @Mohammad points out, lookbehind (the first part in parentheses) is a new feature. So you can tweak my approach to:

const str = 'start:hello::brave new world:end'
const matches = str.match(/:([^:]+)(?=:)/g).map(s => s.slice(1));
console.log(matches);
pwilcox
  • 5,542
  • 1
  • 19
  • 31
1

You current regex :[^\s]+: matches a : and then uses a negated character class to match not a whitespace character. That would match until the end of your example string.

Then it would match a : again which is the last : in the string resulting in :hello::world:

What you could do is to use a capturing group and match not a colon ([^:]+) between colons and in the result get the first capturing group. Note that you don't have to escape the colon:

:([^:]+):

Regex demo

const regex = /:([^:]+):/g;
const str = `:hello::world:`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log(m[1]);
}
The fourth bird
  • 154,723
  • 16
  • 55
  • 70