4

I have a regex: /(?<!\<)\<[a-zA-Z0-9. _]+\>/g. Works fine in browser console if I do "(<<a1>> * <b1> * <c1> * <d1>) * <<e1>>".match(/(?<!\<)\<[a-zA-Z0-9. _]+\>/g).

Same line of code throws SyntaxError: Invalid regular expression: /(?<!<)<([a-zA-Z0-9. _]+)>/: Invalid group when executed in Node.js.

I want to match all variables in my string enclosed in < and > ignore them if enclosed by << and >>.

Abhijit Borade
  • 512
  • 4
  • 18

2 Answers2

3

As an answer as well (more space):
Unless node.js uses it's own regex engine and not the JavaScript one, lookbehinds are not supported in JS, thus (?<!) cannot work. To somewhat mimic this feature from other programming languages, have a look at Flagrant Badassery or use additional packages like node-re2 or node-perl-regex.

As for the differences between Browsers, Chrome does support lookbehinds.

Jan
  • 42,290
  • 8
  • 54
  • 79
1

You can use this regex (might need slight changes, depending if you want to detect beginning/end of lines, or these kind of subtilities). I added a caturing group around the value inside the <> because this regex will also match the char before the < and after the >.

if your <> can be placed at beginning/end of string:

/(?:[^<]|^)\<([a-zA-Z0-9. _]+)\>(?:[^<]|$)/g

If you don't need:

/(?:[^<])\<([a-zA-Z0-9. _]+)\>(?:[^<])/g

NOTE: Not sure of this, but might be quicker than a negative lookbehind.

EDIT: from your comments, i'm not sure you know capturing groups. It allows you to extract parts of your regex, not obligatory the whole matched expression.

To use them in Javascript see this example (note that you have to remove the / at the start and end of the regex and escape the \ too for regex objects):

var myRegex = new RegExp('(?:[^<]|^)\\<([a-zA-Z0-9. _]+)\\>(?:[^<]|$)', 'g'), testStr = '(<<a1>> * <b1> * <c1> * <d1>) * <<e1>>', match, elem = document.getElementById('result');

while (match = myRegex.exec(testStr)) {
  elem.innerHTML = elem.innerHTML + match[1] + '<br>';
}
<div id="result"></div>
Kaddath
  • 5,933
  • 1
  • 9
  • 23
  • It gave me `[ ' ', ' ', ' )' ]` this array. It took unwanted chars. I want it to return `[ '', '', '' ]` – Abhijit Borade Jan 15 '18 at 13:44
  • I added a commentary about that, that's why I added a capturing group to the regex. It matches the chars before and after, but in the capturing groups you will have the values that are inside the `<>`. If you really want the `<>` in the capturing groups, you can change to: `/(?:[^<]|^)(\<[a-zA-Z0-9. _]+\>)(?:[^<]|$)/g` – Kaddath Jan 15 '18 at 13:50
  • it works for me: https://regex101.com/r/2fppPC/2 what didn't work exactly? – Kaddath Jan 15 '18 at 13:58
  • It is taking single surrounding characters along. – Abhijit Borade Jan 15 '18 at 14:01
  • @A.B. i edited my answer, tell me if you still have problems – Kaddath Jan 15 '18 at 14:12
  • Okay. I'll loop through and add <> manually to each item I get. Thanks by the way. – Abhijit Borade Jan 15 '18 at 14:50
  • @A.B. not obliged to add the `<>` manually, you can use the modified regex in my second comment if you want to keep them – Kaddath Jan 15 '18 at 14:51