Positive Look Behind in JavaScript Regular Expression

Positive look behind in JavaScript regular expression

Lookbehind assertions were recently finalised for JavaScript and will be in the next publication of the ECMA-262 specification. They are supported in Chrome 66 (Opera 53), but no other major browsers at the time of writing (caniuse).

var str = 'Text:"How secure is my information?"',
reg = /(?<=Text:")[^"]+(?=")/;

str.match(reg)[0];
// -> How secure is my information?

Older browsers do not support lookbehind in JavaScript regular expression. You have to use capturing parenthesis for expressions like this one instead:

var str = 'Text:"How secure is my information?"',
reg = /Text:"([^"]+)"/;

str.match(reg)[1];
// -> How secure is my information?

This will not cover all the lookbehind assertion use cases, however.

Regex : Using an anchor with positive lookbehind

The problem with ^(?<=foo:)\d+ pattern is that ^ matches the start of the string and (?<=foo) lookbehind fails the match if there is no foo immediately to the left of the current location - and there is no text before the start of the string.

You could fix it as

const regex = new RegExp(/(?<=^foo:)\d+/);

Here, (?<=^foo:) lookbehind checks for foo at the start of the string, but tests each location in the string since ^ is no longer the part of the consuming pattern.

In JS, for better portability across browsers, you'd better use a capturing group rather than a positive lookbehind (and also, you may directly use the regex literal notation, no need to use /.../ with constructor notation):

var str = "foo:25"var regex = /^foo:(\d+)/;console.log(regex.exec(str)[1]);

JS regex positive look behind * not greedy when it should?

FROM TC39 DOCS lookbehind proposal

Patterns normally match starting from the leftmost sub-pattern and move on to the sub-pattern on the right if the left sub-pattern succeeds. When contained within a lookbehind assertion, the order of matching would be reversed. Patterns would match starting from the rightmost sub-pattern and advance to the left instead. For example, given /(?<=\$\d+\.)\d+/, the pattern would first find a number and ensure first that it is preceded by . going backward, then \d+ starting from ., and lastly $ starting from where \d+ within the assertion begins. The backtracking direction would also be reversed as a result of this.


Since your [^\n,]+ will match all the characters except new line and , so it will capture : also and your lookbehind will not see it as it is already captured by assertions after lookbehind,

what you can do is use + which will makes sure you match atleast one space or :

'password: "something"'.replace(/(?<=password[ :]+)[^\n,]+/i, '*****') 

How to implement positive lookbehind of regular expressions in Javascript

The solution was in our face. Sorry for my late.

The final regular expression was thus:

\b(foo\b\=[^&#]*)

The especial character \b set a boundary word for matching, then, for example, it doesn't match "nonfoo=bar", but match "foo", "foo=bar" and doesn't include nothing before "foo" (works it as positive lookbehind), but if the word is after the URI Hash it is also matched (for now there is no way to solve this).

JavaScript regex: Positive lookbehind alternative (for Safari and other browsers that do not support lookbehinds)

Turn the lookbehind in a consuming pattern and use a capturing group:

And use it as shown below:

var s = "some string.005";
var rx = /\.\d\d(\d)/;
var m = s.match(/\.\d\d(\d)/);
if (m) {
console.log(m[1]);
}

What is a good JS/Regex Positive Lookbehind Alternative in Safari for splitting text including hyphens?

The .split(/\s+|(?<=-)/) operation means the string is split into chunks of non-whitespace chars and at the locations right after a - char. It means you can extract any chunks of chars other than whitespace with an optional hyphen right after, or any other hyphen (that will actually be the hyphen(s) right after the first alternative).

const words = text.match(/[^\s-]+-?|-/g)

See the regex demo. Details:

  • [^\s-]+-? - one or more chars other than whitespace and - and then an optional hyphen
  • | - or
  • - - a hyphen.

See the JavaScript demo:

const text = "Self-Sizing Text in a Circle";
const words = text.match(/[^\s-]+-?|-/g)
console.log(words);

How to make this positive lookbehind regular expression run in Safari

You may use

.replace(/(a)(?=b)|(b)(?=a)/g, '$1$2|')

See the regex demo online.

Details

  • (a)(?=b) - matches and captures a into Group 1 if there is b immediately on the right
  • | - or
  • (b)(?=a) - matches and captures b into Group 2 if there is a immediately to the right of the current location.

The replacement is Group 1 + Group 2 vaues (only one of them will be populated with text upon a match) and a | char.

See the JS demo below:

var rx = /(a)(?=b)|(b)(?=a)/g;var strs = ['aba', 'abab', 'aaabbbababab'];for (var s of strs) {   console.log(s, '=>', s.replace(rx, '$1$2|'));}


Related Topics



Leave a reply



Submit