3

I'm trying to parse string in JavaScript and find all unique words, which starts with : symbol. I wrote that regular expression for this purpose:

/(:[A-z]\w+)(?!.*\1)/g

It works fine for this string:

"test :one :one test :one test :two".match(/(:[A-z]\w+)(?!.*\1)/g)

And result is [':one', ':two'] Online example #1

But, if after word goes new line symbol

"test :one\n :one test :one test :two".match(/(:[A-z]\w+)(?!.*\1)/ig)

Regex not working properly and returns [':one', ':one', ':two'] Online example #2

How to modify this regex and get only unique results?

Thomas Ayoub
  • 29,063
  • 15
  • 95
  • 142
Javasick
  • 2,753
  • 1
  • 23
  • 35

1 Answers1

3

You need to use [\s\S] instead of . to make sure the check may go as far as the end of string (not just line) and [a-zA-Z] instead of [A-z] (see Why is this regex allowing a caret?):

/(:[a-z]\w+)(?![\s\S]*\1)/gi

See the regex demo

var re = /(:[a-z]\w+)(?![\s\S]*\1)/gi; 
var str = 'test :one\n :one test :one test :two';
console.log(str.match(re));
//or, get rid of the inital :
console.log(str.match(re).map(function(x){return x.substr(1);}));
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Just in case: I added another line of code to get rid of the initial `:`s if you need that. Certainly it can be done with inner capturing group and then iterate through the matches with `RegExp#exec`, but why not reuse your code. – Wiktor Stribiżew Sep 07 '16 at 12:44