I have a regex to replace numbers in a string with the value @p but I want to replace the same numbers with the same @p1 and then @p2 and @p3 and so on.
This is the sample string
23 44 56 83 23 83 103 6573 56
My current simple replacement would return this
@p @p @p @p @p @p @p @p @p
what I want is this
@p1 @p2 @p3 @p4 @p1 @p4 @p5 @p6 @p3
So the same number would return the same @p number .
My regex matching string is this @"\b[0123456789] \b"
so currently I do this
public static System.Text.RegularExpressions.Regex Reg_pass_numbers = new
System.Text.RegularExpressions.Regex(@"\b[0123456789] \b");
StringHolder = Reg_pass_Hex.Replace(StringHolder, "@p");
StringHolder holds my input string .
Can regex help with this?
CodePudding user response:
Agree with Llama. A MatchEvaluator is a piece of code that specifies what value should be used for replacement during a Regex replace
var r = new Regex(@"\d ");
var i = "23 32 23";
var d = new Dictionary<string, int>();
var x = 1;
var o = r.Replace(
i,
new MatchEvaluator(m => d.TryGetValue(m.Value, out var v)? $"@p{v}" : $"p{d[m.Value]=x }")
);
There's a bit to unpick in this so..
- your Regex can be simplified to just "one or more digits".
- we have a variable x that we increment every time we find a new match we never saw before
- we have a dictionary that tracks matches we saw
- the match evaluator code gets the matched value eg "23" in m.Value
- we try get the dictionary value into v; if it succeeds we use v. If it doesn't we add a new dictionary entry for m.Value with the current value of x and then increment x
If you want to make some sql parameters out of this and want to know what values go with what parameters, enumerate the whole dictionary : the key value pair's Value is the p number and the Key is the value string
CodePudding user response:
You can use Regex.Replace
, but when replacing you can check if match
appeared earlier with help of dictionary:
// try adding a new match
dict.TryAdd(m.Value, dict.Count 1)
? dict.Count // succeed, just return its number
: dict[m.Value] // failed to add, the match already exists, take its number
Code:
string source = "23 44 56 83 23 83 103 6573 56";
Dictionary<string, int> dict = new Dictionary<string, int>();
string result = Regex.Replace(
source,
"[0-9] ",
m => $"@p{(dict.TryAdd(m.Value, dict.Count 1) ? dict.Count : dict[m.Value])}");