4

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
apine
  • 45
  • 5

2 Answers2

2

For the given example, you could match 1+ digits followed by an optional p and an optional x.

\d+p?x?

Regex demo

Also matching a decimal part:

\d+(?:\.\d+)?p?x?

The pattern matches:

  • \d+ Match 1+ digits
  • (?:\.\d+)? Match an optional decimal part
  • p?x? Match an optional p and optional x

Regex demo

And replace with an *

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

replaced_str = str.replace(/\d+p?x?/g, '*');
console.log(replaced_str);

Output

*y...*y...*...*px...*...*ypx
The fourth bird
  • 154,723
  • 16
  • 55
  • 70
  • 1
    Thanks for your solution, I used it but I am accepting @Wiktor answer because it is answering to my thought process from which the question came. – apine Jul 23 '21 at 04:50
1

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.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563