'Pad number with variable length zeroes using REGEX
I have a situation where client inputs a number, and I need to validate that number by padding a certain number of zeroes in front of it. The max length of the field that I validate is 9 digits, so if client enters '123', I need to pad it with 6 zeros in front of it and validate. Sounds easy enough, right?
Well, here is the kicker, I have no code-control over any part of the process. The only things available to me are 2 'properties' - a regex pattern and a regex replace that already existing code uses to process input.
So, is it possible to pad an input using a regex pattern with a regex replace? Again, I have no access to the code, so I cannot apply solution such as this Pad left with zeroes
What I can do is define a search pattern and a replace pattern that already existing code is using.
Here is what I am looking for:
INPUT OUTPUT
1 000000001
12 000000012
123 000000123
12345678 012345678
123456789 123456789
Currently what I have for pattern is:
([0-9]{1,9})
and for replace:
000000000$1
But it doesn't do the job I need, it adds a fixed number of zeroes in front of the input, not a variable number. I suspect the task is impossible, given the restrictions I am working under, but I thought id ask anyway.
PS: the language of the code that reads regex is .NET (C#)
EDIT 1: Just to reiterate, I cannot change/alter code in any way, I cannot even see it. I assume this is what the existing code does:
Regex rgx = new Regex(pattern);
string result = rgx.Replace(input, replacement);
pattern
and replacement
are strings being read from a configuration file, and I can change the values of those 2 strings. That's it. I cannot alter code reading it nor can I loop it to regex it twice or anything.
EDIT 2: Not exactly what I'm looking for but (VB.NET code):
Dim result As String = Regex.Replace(input, pattern, Function(match As Match)
Dim v As String = match.ToString()
Return String.Format("{0:000000000}", Val(v))
End Function)
Problem is, the Function
is code, but if I stick that into property it will be read as a string and will not execute as code but as a replacement string. If I could only figure out how to make that string be treated as code, that would solve my issue.
EDIT 3: optimized code from EDIT 2(this time in C#):
var result = Regex.Replace(input, pattern, (v) => string.Format("{0:000000000}", double.Parse(v.Value)));
Still cannot figure out how to execute this piece of code (v) => string.Format("{0:000000000}", double.Parse(v.Value))
without changing code on the server (which I have no access to), because it is stored as string. It feels like impossible to do without access to change code on the server.
EDIT 4: Got a look at the server code that executes the regex:
searchVal = Regex.Replace(accountNumber, pattern, replace);
The "cannot change code" restriction still applies, so my suggestion from previous edit remains unreachable because it is treated as string and not code. I think this is an impossible task, given the restrictions i am working under.
Thank you all who tried to help
Solution 1:[1]
As you said, .PadLeft()
really is the way to go about this, but you mention that you can't use it. Unfortunately, C# doesn't support conditional replacements for regex. I think the easiest option for you would be to create 8 different regular expressions as such:
\b([1-9])\b 00000000$1
\b([1-9]\d)\b 0000000$1
\b([1-9]\d{2})\b 000000$1
\b([1-9]\d{3})\b 00000$1
\b([1-9]\d{4})\b 0000$1
\b([1-9]\d{5})\b 000$1
\b([1-9]\d{6})\b 00$1
\b([1-9]\d{7})\b 0$1
Alternatively, doing all of this in one regex is possible, but you'd need to append a dictionary to the input as the following suggests:
^([1-9](?=.*1\t+(?<x>0+))|[1-9]\d(?=.*2\t+(?<x>0+))|[1-9]\d{2}(?=.*3\t+(?<x>0+))|[1-9]\d{3}(?=.*4\t+(?<x>0+))|[1-9]\d{4}(?=.*5\t+(?<x>0+))|[1-9]\d{5}(?=.*6\t+(?<x>0+))|[1-9]\d{6}(?=.*7\t+(?<x>0+))|[1-9]\d{7}(?=.*8\t+(?<x>0+)))\b
Appending the following (note that SO shows spaces, but the numbers are separated by tabs):
1 00000000
2 0000000
3 000000
4 00000
5 0000
6 000
7 00
8 0
Replacement: ${x}$1
How to add the dictionary? Well, if you have the ability to append it to the input that's the easiest option. Otherwise, using regex you can use \z
as seen here. You'd then have to run the regex above to use the dictionary.
Replacement: \n1\t00000000\n2\t0000000\n3\t000000\n4\t00000\n5\t0000\n6\t000\n7\t00\n8\t0
If you're unable to run multiple regular expressions on a single input, I'm afraid what you're trying to accomplish cannot be done as each method requires at least 2 runs over the input to give you the expected output.
Solution 2:[2]
You could not use regex but the built in C# $""
to generate the string. For example $"{userInput:D9}"
will pad the number to be nine digits long.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Tyler2P |