Search code examples
javascriptregexstr-replacestring-matchingregexp-replace

how to match bigger word first, from multiple words separated by OR operator in RegExp ? using java script


I need a regex to first match a numbers with 'px' after it, and then match remaining numbers having 'p' after it.
I want to replace parts of string, that are number or a number having 'p' or 'px' after it by '*' character.

a regexp i tried /\d+(\.\d+)?(p|px)?/g , but its not matching 'px' its only matching 'p'.

  • example string, before any replacements to it.: 12pxy...12py...12px...12ppx...12...12ypx
  • here parts that should be replaced are in bold: 12pxy...12py...12px...12ppx...12...12ypx
  • expected result after doing all replacements : *y...*y...*...*px...*...*ypx

following code that I tried, is replacing the number and 'p' but not 'px'.

str = "12pxy...12py...12px...12ppx...12...12ypx";

replaced_str = str.replace(/\d+(\.\d+)?(p|px)?/g, '*');

console.log(replaced_str); 
// output is: *xy...*y...*x...*px...*...*ypx
// I wanted : *y...*y...*...*px...*...*ypx


Solution

  • its not matching 'px' its only matching 'p'

    That is because the (p|px)? alternation is not anchored at the pattern end, and the first alternative always wins since p is a prefix of px, see "Remember That The Regex Engine Is Eager".

    What you can do is swap the alternatives, (px|p)?, or re-write (?:px?)?. Also, you can use non-capturing groups here to avoid extra overhead related to capture mmemory allocation:

    str = "12pxy...12py...12px...12ppx...12...12ypx";
    replaced_str = str.replace(/\d+(?:\.\d+)?(?:px?)?/g, '*');
    console.log(replaced_str); 
    // output: *y...*y...*...*px...*...*ypx

    See the regex demo. Details:

    • \d+ - one or more digits
    • (?:\.\d+)? - an optional occurrence of a dot and one or more digits
    • (?:px?)? - an optional occurrence of p followed with an optional x.