How can I display numbers with 20 in front of the var? (i.e. \20172018\INV instead of \1718\INV)
Insert your 20 at particular places by building a new string from substrings. Assuming your variable is in a string called s:
string newString = s.Substring(0,1) + "20" + s.Substring(1,2) + "20" + s.Substring(3,6);
How do you determine where the 20 goes? Is it after every two digits??
The regular expression var r = Regex.Replace("1718\\NV", "\\d{2}", "20$&"); for example assumes that you are looking for 2 digits each time (that's what the {2} means) and places the 20 in front of each pair of digits. It returns 20172018\\NV. If you want to place the 20 in front of each digit separately, then modify the RegEx pattern (2nd parameter). var r = Regex.Replace("1718\\NV", "\\d", "20$&"); returns 201207201208\\NV
Related
So I have the following regex.replace in C#:
Regex.Replace(inputString, #"^([^,]*,){5}(.*)", #"$1somestring,$2");
where 5 is a variable number in code, but that's not really relevant since at the time of execution it will always have a set value (like 5, for example). Same with somestring,.
Essentially I want to input somestring, between the two groups. The output works for somestring,$2, but $1 is just printed as $1. So say whatever (.*) grabs = "2, a, f2" the resulting string I'd get out is $1somestring,2,a,f2 no matter what $1 is. Is this because of the repeating group feature {5}? If so, how do I grab the collection of repeats and put it in place of where I have $1 right now?
Edit: I know the first group captures correctly, as well. I grab the content of somestring, using this regex:
Regex.Match(line, #"^([^,]*,){5}([0-9]+\.[0-9]+),.*");
The first part is identical the the first group in the replacement regex, and it works fine, so there shouldn't be an issue (and they're both used on the same string).
Edit2:
Ok I'll try to explain more of the process since someone said it was hard to understand. I have three variables, line a string I work with, and latIndex and lonIndex which are just ints (tells me between what ,'s two doubles I look for are located). I have the two following matches:
var latitudeMatch = Regex.Match(line, #"^([^,]*,){" + latIndex + #"}([0-9]+\.[0-9]+),.*");
var longitudeMatch = Regex.Match(line, #"^([^,]*,){" + lonIndex + #"}([0-9]+\.[0-9]+),.*");
I then grab the doubles:
var latitude = latitudeMatch.Groups[2].Value;
var longitude = longitudeMatch.Groups[2].Value;
I use these doubles to get a string from a web API, which i store in a variable called veiRef. Then I want to insert these after the doubles, using the following code (insert after lat or lon, depending on which one appears last):
if (latIndex > lonIndex)
{
line = Regex.Replace(line, #"^([^,]*,){" + (latIndex+1) + #"}(.*)",$#"$1{veiRef},$2");
}
else
{
line = Regex.Replace(line, #"^([^,]*,){" + (lonIndex + 1) + #"}(.*)", $#"$1{veiRef},$2");
}
However, this results in a string line which doesn't have the content of $1 inserted before it ($2 works fine).
You have a repeated capturing group at the start of the pattern that you need to turn into a non-capturing one and wrap with a capturing group. Then, you may access the whole part of the match with the $1 backreference.
var line = "a, s, f, double, double, 12, sd, 1";
var latIndex = 5;
var pat = $#"^((?:[^,]*,){{{latIndex+1}}})(.*)";
// Console.WriteLine(pat); // => ^((?:[^,]*,){6})(.*)
var veiRef = "str";
line = Regex.Replace(line, pat, $"${{1}}{veiRef.Replace("$","$$")}$2");
Console.WriteLine(line); // => a, s, f, double, double, 12,str sd, 1
See the C# demo
The pattern - ^((?:[^,]*,){6})(.*) - now contains ((?:[^,]*,){6}) after ^, and this is now what $1 holds after a match is found.
Since your replacement string is dynamic, you need to make sure any $ inside gets doubled (hence, .Replace("$","$$")) and that the first backreference is unambiguous, thus it should look like ${1} (it will work regardless whether the veiRef starts with a digit or not).
Replacement string in details:
It is an interpolated string literal...
$" - declaration of the interpolated string literal (start)
${{1}} - a literal ${1} string (the { and } must be doubled to denote literal symbols)
{veiRef.Replace("$","$$")} - a piece of C# code inside the interpolated string literal (we delimit this part where code is permitted with single {...})
$2 - a literal $2 string
" - end of the interpolated string literal.
Adding an extra group around the repeating capturing group seems to provide the desired output for the example you gave.
Regex.Replace("a, s, f, double, double, 12, sd, 1", #"^(([^,]*,){5})(.*)", #"$1somestring,$3");
I'm not an expert on RegEx and someone can probably explain it better than I, but:-
Group 1 is the set of 5 repeating capture groups
Group 2 is the last of the repeating capture groups
Group 3 is the text after the 5 repeating capture groups.
I have WPF application where the users are able to change the product number of a product connected to the computer with USB. The sticker on the product lists the product number in this format: 111 22 33-44.
Today the users may only enter digits (111223344) in the textbox. The input is validated with regex that checks for nine digits. But now the client wants the users to be able to either:
Enter the number as digits only and format the string as it is being typed. When the user has typed "1112" it should automatically be formatted as "111 2" in the textbox and so on. When user has entered all nine digits it should look like 111 22 33-44
Enter the number as it is written on the sticker (with spaces, etc).
But at the same time the product number must be validated to include only nine digits. The spaces and "-" must be invisible
I could've easily solved this in code, but the problem here is that this validation/formatting must be fully configurable in a config file. There are various categories of products that can be serviced by this application and the format of the product number may vary.
Is this solvable in a fairly easy way with regex? I really can't see how i can combine the two, validation and formatting:
^\d{9}$ - for validating nine digits
(\w{3})(\w{2})?(\w{2})?(\w{2})? - for formatting together with replacement pattern $1 $2 $3-$4. This pattern does however only format nine digits without spaces and "-"
Any suggestions?
EDIT:
It seems like i would need to use at least three regex patterns for this to work:
for validating the valid product number (not the display value). Is it 9 digits?
for formatting the display value (123456789 = 123 45 67-89)
stripping the added characters from the formatting (blanks and -)
Maybe a simpler solution would be to keep the current validation (for example ^\d{9}$) that validates the raw value, and then simply add a setting called DisplayMask where the people that are responsible for the configuration can enter something like this:
"### ## ##-##"
And then i write code that uses this mask for formatting the display value. This has several advantages:
Very easy to understand for the people responsible for the configurations
This will also enable me to easily retrieve all character that needs to be stripped from the entered value by simply getting the displaymask and remove all #. The characters that are left are the ones that must be stripped from the product number before they're written to the product hardware.
Also makes it very easy to set the max length of the textbox. Max length of product number raw value + number of added characters from display mask.
If you'd like to make this configurable, the key is the Regex class in System.Text.RegularExpressions namespace.
Storing the regular expression in an external config file could then be easily imported and used in matching, such as Regex.IsMatch(), especially IsMatch(string, string).
Have a look at this one Regex in PreviewTextInput: only decimals between 0.0 and 1.0
you can use PreviewTextInput event here,then use Regex.Replace to set the format, here is an example
string inputStr = "111223";//e.Text;
inputStr = Regex.Replace(inputStr, #"\D", string.Empty);
if (inputStr.Length > 0)
{
inputStr = inputStr.Substring(0, Math.Min(9, inputStr.Length));
List<string[]> tmp = new List<string[]>() { new string[] { "7", "-" }, new string[] { "5", " " }, new string[] { "3", " " } };
foreach (var arr in tmp)
{
inputStr = Regex.Replace(inputStr, #"(?<=^\d{" + arr[0] + "})", arr[1]);
}
}
Console.WriteLine(inputStr);
First off, after the text is formatted you have an entry with a length of 12. I would set the TextBox.MaxLength = 12 to limit the amount of data that can be entered.
As far as validating, there's probably a "cleaner" way of doing this, but to start with you can have a series of Regex.IsMatch() conditions that will auto format the input.
For example:
1112 => 111 2
111 223 => 111 22 3
111 22 334 => 111 22 33-4
Then there's a final Regex.IsMatch() check that the input is in the format of
### ## ##-##
Code Sample:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string text = textBox1.Text;
if (Regex.IsMatch(text, "\\d{4}"))
{
textBox1.Text = Regex.Replace(text, "(\\d{3})(\\d)", "$1 $2");
}
else if (Regex.IsMatch(text, "\\d{3} \\d{3}"))
{
textBox1.Text = Regex.Replace(text, "(\\d{3} \\d{2})(\\d)", "$1 $2");
}
else if (Regex.IsMatch(text, "\\d{3} \\d{2} \\d{3}"))
{
textBox1.Text = Regex.Replace(text, "(\\d{3} \\d{2} \\d{2})(\\d)", "$1-$2");
}
else if (!Regex.IsMatch(text, "\\d{3} \\d{2} \\d{2}-\\d{2}"))
{
// Invalid entry
}
// Keep the cursor at the end of the input
textBox1.SelectionStart = textBox1.Text.Length;
}
Hi i need a Regex Expression for extracting only floating point numbers from right to left
Example string
Earning per Equity Share (in ) face value of 2 each26 1,675.10
1,252.56
My current Regex
(\+|-)?[0-9][0-9]*(\,[0-9]*)?(\.[0-9]*)? with Rex options-Right to left
but
Current Output is
1,252.56
1,675.10
26
2
However i do not want to match on 26 or 2
Please help me
Maybe something like this will help
Regex
/[-+]?[0-9,\.]*([,\.])[0-9]*/g
Example input
Earning -34 5 b4 pe8r blah4 t3st + - (in) 1,252.56 face
-12234,23423.342 of 1,675.10 1,252.56
Matches
1,252.56
-12234,23423.342
1,675.10
1,252.56
Explanation
[-+]? match a single character present in the list below
Quantifier: ? Between zero and one time, as many times as possible, giving back as needed [greedy]
-+ a single character in the list -+ literally
[0-9,\.]* match a single character present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
, the literal character ,
\. matches the character . literally
1st Capturing group ([,\.])
[,\.] match a single character present in the list below
, the literal character ,
\. matches the character . literally
[0-9]* match a single character present in the list below
Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
0-9 a single character in the range between 0 and 9
g modifier: global. All matches (don't return on first match)
Although this is a Regex question this is also taged as C#.
Below is an example of how you might get a little bit more control over your output.
It's also culture-specific and only picks up numbers with a decimal place, and has no false positives.
Method
private List<double> GetNumbers(string input)
{
// declare result
var resultList = new List<double>();
// if input is empty return empty results
if (string.IsNullOrEmpty(input))
{
return resultList;
}
// Split input in to words, exclude empty entries
var words = input.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// set your desirted culture
var culture = CultureInfo.CreateSpecificCulture("en-GB");
// Refine words into a list that represents potential numbers
// must have decimal place, must not start or end with decimal place
var refinedList = words.Where(x => x.Contains(".") && !x.StartsWith(".") && !x.EndsWith("."));
foreach (var word in refinedList)
{
double value;
// parse words using designated culture, and the Number option of double.TryParse
if (double.TryParse(word, NumberStyles.Number, culture, out value))
{
resultList.Add(value);
}
}
return resultList;
}
Usage
var testString = "Earning -34 5 b4 , . 234. 234, ,345 45.345 $234234 234.3453.345 $23423.2342 +234 -23423 pe8r blah4 t3st + - (in) 1,252.56 face -12234,23423.342 of 1,675.10 1,252.56";
var results = GetNumbers(testString);
foreach (var item in results)
{
Debug.WriteLine("{0}", item);
}
Output
45.345
1252.56
-1223423423.342
1675.1
1252.56
Additional Notes
You can learn more about double.TryParse and its options here.
You can learn more about the CultureInfo Class here.
ok i found this for removing all 'junk' that is not a number from a string
TextIN = " 0 . 1 ,2 ; 3 4 -5 6 ,7 ,8; 9 "
string justNumbers = new String(textIN.Where(Char.IsDigit).ToArray());
= "0123456789"
this removes all "junk" from my string leaving me just the numbers, but still how i can modify this ,
so i can have at least one delimiter for example a ' , ' b etween my numbers like "0,1,2,3,4,5,6,7,8,9" because i need to delimit this number so i can put them in an array of ints and work with them and there are not always just one digit numbers i may have 105 , 85692 etc..
any help please ?!
You can also convert to numeric values like this:
int[] numbers = Regex.Matches(textIN, "(-?[0-9]+)").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();
#L.B: agreed, but nthere might be negative values, too.
string test = string.Join(",", textIN.Where(Char.IsDigit));
For n digit numbers you can use regex.
string s = String.Join(",",
Regex.Matches(textIN,#"\d+").Cast<Match>().Select(m=>m.Value));
string justNumbers = new String(textIN.Where(Char.IsDigit).ToArray()); = "0123456789"
string[] words = justNumbers.Split(',');
will seperate the string into an array of numbers, delimited by commas.
There are a lot of numbers like 200 20.5 329.2...in a file. Now, I need replace every number A with A*0.8. Is there any simple method to replace original value with another based on original value?
Best Regards,
Try this one:
String s = "This is the number 2.5. And this is 7";
s = Regex.Replace(s, #"[+-]?\d+(\.\d*)?", m => {return (Double.Parse(m.ToString())*0.8).ToString();});
// s contains "This is the number 2. And this is 5.6"
Edit: Added the plus/minus sign as an optional character in front. To avoid catching the 5 in 3-5 as negative, you could use ((?<=\s)[+-])? instead of [+-]
Using lambda and slightly better handling of cases like The value is .5. Next sentence:
var s = "This is the number 2.5. And this is 7, .5, 5. Yes.";
var result = Regex.Replace(s, #"[+-]?(\d*\.)?\d+", m => (double.Parse(m.Value) * 0.8).ToString());