Reputation: 2283
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
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
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
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