Search code examples
javascriptregexreplacereplaceall

Positive lookahead capturing too much JS


I am struggling to insert a line break before any dates which occur after "notes:" in a string.
My regex seems to be capturing all text prior to the first date after "notes:"
Any help with the JavaScript very much appreciated.

const mystring = 'wed and thurs and notes: are just so interesting 02-03-2019 on a new line please 04-05-2020 on another line please'

mystring.replaceAll(/(?<=notes:).*?(\d{1,2}-\d{1,2}-\d{4})/g, function(capture){

return '<br>' + capture; 

}
);

my desired output:

wed and thrus and notes: are just so interesting <br> 02-03-2019 on a new line please <br> 04-05-2020 on another line please

Solution

  • You can use

    const mystring = 'wed and thurs and notes: are just so interesting 02-03-2019 on a new line please 04-05-2020 on another line please wed and thurs and notes: are just so interesting 02/03/2019 on a new line please 04/05/2020 on another line please';
    console.log(mystring.replace(/(?<=notes:.*?)\b\d{1,2}([-\/])\d{1,2}\1\d{4}\b/g, '<br> $&'));

    See the regex demo.

    The regex matches

    • (?<=notes:.*?) - a location in string that is immediately preceded with notes: and any zero or more chars other than line break chars as few as possible
    • \b - a word boundary (omit if you want to match dates glued to letters, digits or underscores)
    • \d{1,2} - one or two digits
    • ([-\/]) - Group 1: - or /
    • \d{1,2} - one or two digits
    • \1 - same value as in Group 1, - or /
    • \d{4} - four digits
    • \b - a word boundary (omit if you want to match dates glued to letters, digits or underscores)

    The $& construct in the replacement pattern is a backreference to the whole match.