javascriptregexregex-lookaroundsnegative-lookbehind

Javascript regexes - Lookbehind and lookahead at the same time


I am trying to create a regex in JavaScript that matches the character b if it is not preceded or followed by the character a.

Apparently, JavaScript regexes don't have negative lookbehind readily implemented, making the task difficult. I came up with the following one, but it does not work.

"ddabdd".replace(new RegExp('(?:(?![a]b(?![a])))*b(?![a])', 'i'),"c");

is the best I could come up with. Here, the b should not match because it has a preceding it, but it matches.

So some examples on what I want to achieve

"ddbdd" matches the b
"b" matches the b
"ddb" matches the b
"bdd" matches the b
"ddabdd" or "ddbadd" does not match the b

Solution

  • It seems you could use a capturing group containing either the beginning of string anchor or a negated character class preceding "b" while using Negative Lookahead to assert that "a" does not follow as well. Then you would simply reference $1 inside of the replacement call along with the rest of your replacement string.

    var s = 'ddbdd b ddb bdd ddabdd ddabdd ddbadd';
    var r = s.replace(/(^|[^a])b(?!a)/gi, '$1c');
    console.log(r); //=> "ddcdd c ddc cdd ddabdd ddabdd ddbadd"
    

    Edit: As @nhahtdh pointed out the comment about consecutive characters, you may consider a callback.

    var s = 'ddbdd b ddb bdd ddabdd ddabdd ddbadd sdfbbfds';
    var r = s.replace(/(a)?b(?!a)/gi, function($0, $1) {
        return $1 ? $0 : 'c';
    });
    console.log(r); //=> "ddcdd c ddc cdd ddabdd ddabdd ddbadd sdfccfds"