In the string below, I need All the decimal numbers are placed in a command like \textnormal{#} if they
- do not belong to a hex color (always in this format: \textcolor{#dddddd} where d can be 0-9, a-f, and/or A-F)
- are not followed by a
pt
\documentclass[16.5pt]{article}\begin{document}$$\textcolor{#FF80C0}{E} \textcolor{#FF0027}{CR} = 4A + 0.031De^1.63 = \textcolor{#0000FF}{{CR}_0}$$\end{document}
So, it should be
\documentclass[16.5pt]{article}\begin{document}$$\textcolor{#FF80C0}{E} \textcolor{#FF0027}{CR} = \textnormal{4}A + \textnormal{0.031}De^\textnormal{1.63} = \textcolor{#0000FF}{{CR}_\textnormal{0}}$$\end{document}
I have tried
Regex.Replace(@"(\d+(?:\.\d+)?)(?![\d.])(?!pt)(?<!#[0-9a-f-A-F]{6})", n => $@"\textnormal{{{n.Value}}}");
But the digits belonging to hex colors are not excluded. Here is the link.
EDIT:
The following piece of code does what I need.
int ib = -1; // begining index of a decimal number
int ie = -1; // end index of a decimal number
for (int i = 0; i < S.Length; i++)
{
if (ib == -1 && (char.IsDigit(S[i]) || S[i] == '.'))
{
if (S[i] == '.' && char.IsDigit(S[i - 1]) == false && char.IsDigit(S[i + 1]) == false)
{
ib = -1;
continue; // The found '.' char is a single dot, not the decimal point of a number.
}
ib = i; // Here is the begining of a decimal number. Now the end of the number should be found.
}
else if (ib != -1 && !(char.IsDigit(S[i]) || S[i] == '.'))
{
ie = i - 1; // Here is the end of the decimal number.
if (S.Substring(ie + 1, "pt".Length) == "pt")
{
i++;
ib = -1;
continue; // The decimal number is followed by a "pt"
}
else if (S.Substring(ib - "FFFFFF".Length, "FFFFFF".Length).Contains('#'))
{
ib = -1;
continue; // The number belongs to a hex color code
}
else
{
S = S.Insert(ie + 1, "}");
S = S.Insert(ib, @"\textnormal{");
ib = -1;
i += @"\textnormal{".Length;
}
}
}