0

I want to match a number in a string: 'abc@2003, or something else @2017' I want to get result [2003, 2007] with match function.

let strReg = 'abc@2003, or something else @2017';
let reg = new RegExp(/(?=(@\d+))\1/);  
strReg.match(reg)  //[ '@2003 ', '@2017 ' ]
let reg1 = new RegExp(/(?=@(\d+))\1/)
strReg.match(reg1) //null, but I expect [2003, 2007]

the result mains '\1' match after '?=', ?=()\1 works, ?=@()\1 not.

javascript only supports backwards, how should I do to match '@' but ignore it?

Borkes
  • 181
  • 1
  • 2
  • 11
  • What's wrong with \d+ – Mr Mystery Guest Jun 15 '17 at 11:01
  • I just focus on "?=@()\1" can not get () match string.  'abc@2003, or something else @2017' -> [2003, 2007] only an example to show my question. – Borkes Jun 15 '17 at 11:50
  • I think I know what`s wrong after looking https://msdn.microsoft.com" api, (?=xxx) is Noncapturing, so '\1' just capture (?=(@\d+)) not (@\d+), and other groups will not be captured too. Noncapturing RegExp start with '?', such as '?=', '?!=', '?<=', '?<!' for save memory. Maybe (?<=@)\d+ can solve my problem, but javascript not support. – Borkes Jun 16 '17 at 03:10

2 Answers2

2

I take it that you want an array of the results, so...

var s = "abc@2003, or something else @2017 not the 2001 though";
var re = /@(\d+)/g;
var result = [];
var match = re.exec(s);
while (match !== null) {
    result.push(parseInt(match[1]));
    match = re.exec(s);
}

console.log(result);

Outputs:

Array [ 2003, 2017 ]

match(0) is the entire match, match(1) is the captured group.

Also, see How do you access the matched groups in a JavaScript regular expression?

Inspired by javascript regex - look behind alternative?, if you want to do it as almost a one-liner:

var re = /(\d+)(?=@)/g; /* write the regex backwards */
var result = [];
s.split('').reverse().join('').match(re).forEach(function (el) { result.push(parseInt(el.split('').reverse().join(''))); });
console.log(result.reverse());

Caveat: Who wrote this programing saying? “Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.”

Andrew Morton
  • 24,203
  • 9
  • 60
  • 84
  • Yes, it works, but I want use more simple way or few code to solve the problem. In other worlds, I want use just one RegExp string to get array [2003, 2007], and I don`t want to use while or for. [@2003, @2007] to [2003, 2007] is easy. my point is "the result mains '\1' match after '?=', ?=()\1 works, ?=@()\1 not." – Borkes Jun 15 '17 at 11:44
  • @Borkes If the string to look in is reversed, you can use a look-behind. – Andrew Morton Jun 15 '17 at 13:42
  • `let reg1 = new RegExp(/(?=(@(\d+)))\1/)` `let reg2 = new RegExp(/(?=(@(\d+)))\2/)` `strReg.match(reg1) // [@2003, @2007]` `strReg.match(reg2) //null` After look-behind, I expect '\1' get whole group (@(\d+)), '\2' get inner group (\d+), but null – Borkes Jun 16 '17 at 01:59
0

Small change to your code does the job as follows:

/@(\d+)/g

number followed by @ will be remembered as you required.

Sai M.
  • 2,548
  • 4
  • 29
  • 46