Mehdi
Mehdi

Reputation: 2283

Regex replace 'whole' decimal numbers not followed by a certain string

I want to replace "whole" decimal numbers not followed by pt with M.

For example, I need to replace 1, 12, and 36.7, but not 45.63 in the following.

string exp = "y=tan^-1(45.63pt)+12sin(-36.7)";

I have already tried

string newExp = Regex.Replace(exp, @"(\d+\.?\d*)(?!pt)", "M");

and it gives

"y=tan^-M(M3pt)+Msin(-M)"

It does make sense to me why it works like this, but I need to get

"y=tan^-M(45.63pt)+Msin(-M)"

Upvotes: 3

Views: 194

Answers (3)

JvdV
JvdV

Reputation: 75990

I think you may assert the point in a string where there are no digits and dots directly followed by "pt":

\b(?![\d.]+pt)\d+(?:\.\d+)?

See the online demo


  • \b - Match a word-boundary.
  • (?![\d.]+pt) - Negative lookahead for 1+ digits and dots followed by "pt".
  • \d+ - 1+ digits.
  • (?: - Open non-capture group:
    • \.\d+ - A literal dot and 1+ digits.
    • )? - Close non-capture group and make it optional.

See the .NET demo

Upvotes: 1

sai kiran
sai kiran

Reputation: 389

Hi there if you need the out put as

   "y=tan^-M(Mpt)+Msin(-M)"

then then newExp should be

   string newExp = Regex.Replace(exp, @"(\d+\.?\d*)", "M");

if output is

 "y=tan^-M(45.63pt)+Msin(-M)"

then newExp should be

 string newExp = Regex.Replace(exp, @"(\d+\.?\d*)(?![.\d]*pt), "M");

Upvotes: 2

Tim Biegeleisen
Tim Biegeleisen

Reputation: 522741

The problem with the regex is that it is still matching a portion of the decimal value 45.63, up to the second-to-last decimal digit. One solution is to add a negative lookahead to the pattern to ensure that we only assert (?!pt) at the real end of every decimal value. This version is working:

string exp = "y=tan^-1(45.63pt)+12sin(-36.7)";
string newExp = Regex.Replace(exp, @"(\d+(?:\.\d+)?)(?![\d.])(?!pt)", "M");
Console.WriteLine(newExp);

This prints:

y=tan^-M(45.63pt)+Msin(-M)

Here is an explanation of the regex pattern used:

(               match and capture:
    \d+         one or more whole number digits
    (?:\.\d+)?  followed by an optional decimal component
)               stop capturing
(?![\d.])       not being followed by another digit or dot
(?!pt)          not followed by pt

Upvotes: 4

Related Questions