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 capturesa
into Group 1 if there isb
immediately on the right|
- or(b)(?=a)
- matches and capturesb
into Group 2 if there isa
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
How to Pass Data to Url from Jqgrid Row If Hyperlink Is Clicked
How to Submit a Form Using Phantomjs
How to Do Two-Way Filtering in Angularjs
JavaScript Number Split into Individual Digits
Testing If a Checkbox Is Checked with Jquery
Convert Object Array to Hash Map, Indexed by an Attribute Value of the Object
What Does ${} (Dollar Sign and Curly Braces) Mean in a String in JavaScript
How to Check If the Url Contains a Given String
How to Reload or Re-Render the Entire Page Using Angularjs
How to Check Whether an Object Is a Date
Utf-8 Word Boundary Regex in JavaScript
Proper Use of Const for Defining Functions
How to Require a Controller in an Angularjs Directive
Is It Safe to Assume Strict Comparison in a JavaScript Switch Statement
Javascript: How to Get Chrome to Break on All Errors
Componentdidmount Equivalent on a React Function/Hooks Component