regex - Javascript Lookbehind with Global Search Overlapped -
there several (sometimes tricky) solutions lookbehind regexps in javascript. but, easiest way, if need zero width! behind expression global search, may overlap. e.g. using /(?<=[01])\d/g
following:
var = "--1--01001--1087---"; a.replace(/(?<=[01])\d/g, "#"); // should return "--1--0####--1##7---" if lookbehind supported
or example: how can create \b
expression works letters ([a-za-z]
). (lookforward no question. js not support lookbehind).
the look-behind through reversal approach seems easiest here. approach best short numeric patterns one.
function revstr(str) { return str.split('').reverse().join(''); } var s = "--1--01001--1087---"; var rxp = /\d(?=[01])/g; var result = revstr(revstr(s).replace(rxp, "#")); document.write(result);
logics:
\d(?=[01])
reversed regex(?<=[01])\d
- we reverse input string
revstr(s)
function - we reverse replacement result again obtain final outcome.
note:
in case need both variable-width look-behind and look-ahead in javascript, can recommend reading javascript regex lookbehind redux article steven levithan, can find sample function showing how implement behavior using xregexp. here functions:
// simulating infinite-length leading lookbehind in javascript. uses xregexp. // captures within lookbehind not included in match results. lazy // repetition in lookbehind may lead unexpected results. (function (xregexp) { function preparelb(lb) { // allow mode modifier before lookbehind var parts = /^((?:\(\?[\w$]+\))?)\(\?<([=!])([\s\s]*)\)$/.exec(lb); return { // $(?!\s) allows use of (?m) in lookbehind lb: xregexp(parts ? parts[1] + "(?:" + parts[3] + ")$(?!\\s)" : lb), // positive or negative lookbehind. use positive if no lookbehind group type: parts ? parts[2] === "=" : !parts }; } xregexp.execlb = function (str, lb, regex) { var pos = 0, match, leftcontext; lb = preparelb(lb); while (match = xregexp.exec(str, regex, pos)) { leftcontext = str.slice(0, match.index); if (lb.type === lb.lb.test(leftcontext)) { return match; } pos = match.index + 1; } return null; }; xregexp.testlb = function (str, lb, regex) { return !!xregexp.execlb(str, lb, regex); }; xregexp.searchlb = function (str, lb, regex) { var match = xregexp.execlb(str, lb, regex); return match ? match.index : -1; }; xregexp.matchalllb = function (str, lb, regex) { var matches = [], pos = 0, match, leftcontext; lb = preparelb(lb); while (match = xregexp.exec(str, regex, pos)) { leftcontext = str.slice(0, match.index); if (lb.type === lb.lb.test(leftcontext)) { matches.push(match[0]); pos = match.index + (match[0].length || 1); } else { pos = match.index + 1; } } return matches; }; xregexp.replacelb = function (str, lb, regex, replacement) { var output = "", pos = 0, lastend = 0, match, leftcontext; lb = preparelb(lb); while (match = xregexp.exec(str, regex, pos)) { leftcontext = str.slice(0, match.index); if (lb.type === lb.lb.test(leftcontext)) { // doesn't work correctly if lookahead in regex looks outside of match output += str.slice(lastend, match.index) + xregexp.replace(match[0], regex, replacement); lastend = match.index + match[0].length; if (!regex.global) { break; } pos = match.index + (match[0].length || 1); } else { pos = match.index + 1; } } return output + str.slice(lastend); }; }(xregexp));
each of these functions takes 3 arguments: string search, lookbehind pattern string (can use xregexp syntax extensions), , main regex. xregexp.replacelb
takes fourth argument replacement value, can string or function.
usage examples follow:
xregexp.execlb("fluffy cat", "(?i)(?<=fluffy\\w+)", xregexp("(?i)(?<first>c)at")); // -> ["cat", "c"] // result has named backref: result.first -> "c" xregexp.execlb("fluffy cat", "(?i)(?<!fluffy\\w+)", /cat/i); // -> null xregexp.testlb("fluffy cat", "(?i)(?<=fluffy\\w+)", /cat/i); // -> true xregexp.testlb("fluffy cat", "(?i)(?<!fluffy\\w+)", /cat/i); // -> false xregexp.searchlb("catwoman's fluffy cat", "(?i)(?<=fluffy\\w+)", /cat/i); // -> 18 xregexp.searchlb("catwoman's fluffy cat", "(?i)(?<!fluffy\\w+)", /cat/i); // -> 0 xregexp.matchalllb("catwoman's cats fluffy cats", "(?i)(?<=fluffy\\w+)", /cat\w*/i); // -> ["cats"] xregexp.matchalllb("catwoman's cats fluffy cats", "(?i)(?<!fluffy\\w+)", /cat\w*/i); // -> ["catwoman", "cats"] xregexp.replacelb("catwoman's fluffy cat cat", "(?i)(?<=fluffy\\w+)", /cat/ig, "dog"); // -> "catwoman's fluffy dog cat" xregexp.replacelb("catwoman's fluffy cat cat", "(?i)(?<!fluffy\\w+)", /cat/ig, "dog"); // -> "dogwoman's fluffy cat dog" xregexp.replacelb("catwoman's fluffy cat cat", "(?i)(?<!fluffy\\w+)", /cat/ig, function ($0) { var first = $0.charat(0); return first === first.touppercase() ? "dog" : "dog"; }); // -> "dogwoman's fluffy cat dog"
Comments
Post a Comment