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:']
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:']
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)
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);
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:
:([^:]+):
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]);
}