0

Working in JavaScript I have strings that might contain words prefixed by an "@". The string might look like this @one two @three. I want a RegExp that finds the words prefixed by the "@" but I don't want to include the "@" itself.

I created a RegExp looking like this /@(\w+)/g but when I match it against my strings the "@" is indeed included. Why is this? I assumed that if I wanted to include it then the "@" would be inside the capturing parentheses like this /(@\w+)/g

var s = '@one two @three'
var matches = s.match(/@(\w+)/g)
// matches is now [ '@one', '@three' ] but I want [ 'one', 'three' ]

Note with the result I currently get, there is of course no problem in getting the array I want, I can just remove the first character of each string. But what I want to know is:

Is it possible to change my RegExp to get the desired result? And: Why are characters outside my capturing parenthesis included in the result? I find it intuitive that only the characters inside the parenthesis should be included.

Ludwig Magnusson
  • 13,964
  • 10
  • 38
  • 53
  • I don't think this question is really a duplicate of the one it's marked as being a duplicate of, but that in turn is because OP has the wrong understanding of the problem. In short, there is nothing wrong with the regex, but the problem is that `match()` doesn't return captured groups if the `g` flag is present. If `g` is not present it does, but then you only get the first match. What you see in `matches` are all full matches of your regex, of which the @ characters are part. A "positive lookbehind" could have fixed this I think but javascript doesn't support that. – Peter Herdenborg Apr 25 '16 at 08:43
  • @PeterHerdenborg If you write this post as an answer and perhaps confirm that there is also no other regexp method that would solve this then I will confirm that as the accepted answer since this is the type of information I am looking for, – Ludwig Magnusson Apr 25 '16 at 09:07
  • I actually intended to make that an answer but it seems you can't add answers now that the question has been marked as duplicate. – Peter Herdenborg Apr 25 '16 at 09:13
  • @Witkor The correct (or at least primary) duplicate for this question should be `https://stackoverflow.com/questions/10901334/i-cant-accurately-understand-how-does-javascripts-method-string-matchregexp`. Would you please update the linked-to duplicate box? That way I can flag the previous comments for removal as no longer required. (This question came up in the Reopen Queue and I'm trying to stop that from happening again.) – robinCTS Nov 20 '17 at 00:46

1 Answers1

1

You need to access first capturing group

var re = /@(\w+)/gm; 
var str = '@one two @three';
var m;

while ((m = re.exec(str)) !== null) {
    print(m[1]);
}

Ideone Demo

JS Demo

var re = /@(\w+)/; 
var arr = ['@one', 'two', '@three'];

arr.forEach(function(str) {
  if (str.match(re))
  document.writeln(str.match(re)[1] + '<br>');
});
rock321987
  • 10,942
  • 1
  • 30
  • 43
  • @WiktorStribiżew Actually I directly imported the code from regex101.. – rock321987 Apr 25 '16 at 08:02
  • While this is a solution on how to arrive at the result I want, I do not find it to be an answer to my question. I have clarified it some. – Ludwig Magnusson Apr 25 '16 at 08:11
  • @LudwigMagnusson do you want to know the reason for why is that happening in your code? – rock321987 Apr 25 '16 at 09:50
  • I want an explanation for why the match function returns what it does and an answer to if it is possible to get what I want by changing the regexp alone. Peter Hedenborg basically explained it in his comment to my question. – Ludwig Magnusson Apr 25 '16 at 10:07
  • 1
    @LudwigMagnusson see **[this](http://stackoverflow.com/questions/10901334/i-cant-accurately-understand-how-does-javascripts-method-string-matchregexp)** about how match works in JS – rock321987 Apr 25 '16 at 10:22