Format String to Match Specific Pattern - c#

I am trying to figure out how to format a string to a specific pattern.
When a user is entering their employee id number, they often get confused on what is expected from them. Because they are often told that their employee id is either a 5 digit or 4 digit number depending on when they were hired.
For example, my employee id number is E004033 but for most of our systems, I just have to enter 4033 and the system will find me.
We are trying to add this to one of our custom pages. Basically what I want to do is format a string to always look like E0XXXXX
So if they enter 4033 the script will convert it to E004033, if they enter something like 0851 it will convert it to E000851 or if they enter 11027 it will convert it to E011027
Is there a way basically add padding zeros and a leading E if they are missing from the users input?

You can simply:
var formattedId = "E" + id.PadLeft(6, '0');
To remove an existing leading E(s)
var text = "E" + val.TrimStart(new[] {'E'}).PadLeft(6, '0');

Make sure the user's input is an integer, then format to 6 spaces using String.Format.
int parsedId;
bool ok = int.TryParse(id, out parsedId);
if (ok)
{
return String.Format("E{0:000000}", parsedId);
}

Related

Remove several dots/commas in string from every decimal number

How can I check for a comma in a number?
Lets assume I have a string which represents a polynomial term that looks like this
string x = "x+1+5,54";
Now the user wants to put in and add a comma which will then be "x1+5,54,"
which is not a number anymore. How can I check this with an if ?
Something like if the last number already contains a comma don't append another one.
Use regular expression.
if (Regex.IsMatch(a, #"^((\d+,?\d*)|(\w?))([-+/]((\d+,?\d*)|(\w?)))*$"))
{
//correct
}
else
{
//incorrect
}
You'll get false, when user inputs extra comma, so you can handle it.

How do you find a delimited/isolated substring with string.contains?

I am trying to parse out and identify some values from strings that I have in a list.
I am using string.Contains to identify the value im looking for, but I am getting hits even if the value is surrounded by other text. How can I make sure I only get a hit if the value is isolated?
Example parse:
Looking for value = "302"
string sale =
"199708. (30), italiano, delim fabricata modella, serialNumber302. tnr F18529302E.";
var result = sale.ToLower().Contains(”302”));
In this example I will get a hit for "serialNumber302" and "F18529302E", which in the context is incorrect since I only want a hit if it finds “302” isolated, like “dontfind302 shouldfind 302”.
Any ideas on how to do this?
If you try Regex, you can define a word boundary using \b:
string sale =
"199708. (30), italiano, delim fabricata modella, serialNumber302. tnr F18529302E.";
bool result = Regex.IsMatch(sale, #"\b302\b"); // false
sale = "A string with 302 isolated";
result = Regex.IsMatch(sale, #"\b302\b"); // true
So 302 will only be found if it is at the start of the string, at the end of the string, or if it is surrounded by non-word characters i.e. not a-z A-Z 0-9 or _
EDIT: From the comments I realiſed that it waſn't clear whether or not "serialNum302" ſhould get a hit. I aſſumed ſo in this anſwer.
I ſee a few eaſy ways you could do this:
1) If the input is always a number as in the example, one option would be to only ſearch for ſubſtrings not ſurrounded by more numbers, by examining all the reſults of an initial ſearch and comparing their neighboring characters againſt the ſtring "0123456789". I really don't think this is the beſt option though, becauſe ſooner or later it's goïng to break when it miſinterprets one of the other bits of data.
2) If the ſtring sale always has the ſeriäl number in the format "serialNumber[Num]", inſtead of juſt looking for Num, look for "serialNumber" + Num, as this is leſs likely to be meſſed up with the other data.
3) From your ſtring, it looks like you have a ſtandardized format that's beïng introduced to the ſyſtem. In this caſe, parſe it in a ſtandardized way, e.g. by ſplitting it into ſubſtrings at the commas, then parſing each ſubſtring differently as it requires.

C# strip out not needed data using REGEX or something different

So i'm trying to strip data from a string because I have in WPF a "preset" input which looks like __,___, now a user must input something like 30,589, but when a user just gives in 5 or 50, it needs to strip the rest (keeping the ,) to propperly make a float of the input value. The code that I have right now looks like this;
if (inp_km.Text == "__,___")
{
team_results.results[inp_tour_part.SelectedIndex].km =
float.Parse("00,000",
NumberStyles.AllowDecimalPoint,
CultureInfo.GetCultureInfo("nl-NL")); // Give the new value
}
else
{
team_results.results[inp_tour_part.SelectedIndex].km =
float.Parse(inp_km.Text,
NumberStyles.AllowDecimalPoint,
CultureInfo.GetCultureInfo("nl-NL")); // Give the new value
}
But this code just check wether the input is left blank or not... Could someone help me out?
Edit
So I've included a screen, this is the input lay-out a user gets;
Os you can see, the inputs are 'pre-filled', the content of such an input is a "string", so, let's say, I type into the first input just 5;
Then the value (retreived in C# by input_name.Text) is 5_:__, but that's a "wrong" value and you can't fill in such things, how could I check if there still is a : or _ in the input.
Also, the bottom input is the same, but then it needs to be filled in completely.
So you want to check either the input is in one of the two forms: 12,345 or 12:34.
This can be done using Regex very easily.
static void Main(string[] args)
{
var inputComma = "12,345";
var inputColon = "98:76";
Regex regexComma = new Regex(#"^\d{2},\d{3}$");
Regex regexColon = new Regex(#"^\d{2}:\d{2}$");
var matchComma = regexComma.Match(inputComma);
if (matchComma.Success)
{
Console.WriteLine(inputComma);
}
Console.WriteLine();
var matchColon = regexColon.Match(inputColon);
if (matchColon.Success)
{
Console.WriteLine(inputColon);
}
Console.ReadLine();
}
NOTE:
You haven't quite clarified the valid formats for your input. The above will evaluate to true strictly for 12,345 format if commas are present (i.e., two digits followed by a comma followed by three digits), and for colon, only numbers of the format 12:34 (two digits before and after the colon) only.
You might want to modify your Regex based on your exact criteria.

Add numeric strings in C# and preserve formating

I have an issue where I need to add two numeric strings "$1,234.56" and "$9,876.54" and get a string "$11,111.10"
I can convert the strings to numbers, perform the addition, but I don't know of a good way to preserve the formatting when I ToString() the result. I can add a couple of if statements along the lines: does the input have dollar sign, decimal point, percent sign and construct the format string accordingly, but this is clunky and will fail if we ever need to support more than one number format.
Does anyone know how to add numeric strings and preserve formatting?
EDIT: To answer the questions. The format of all strings being added at a given time is the same ie: I don't need to worry about adding $ and £ (in fact £ is not currently supported), However, there are several possible formats that are currently supported and more may be added in the future:
$1,234.00; $1,234; 1234; 1,234; 1,234.00; 1234%; 1,234%; 1,234.00%
I would suggest using the first numeric string as a template and create a number format from it:
var posshalves = firstNumericString.Split('.');
var fmthalves = new string[2] { posshalves[0], (posshalves.Length < 2 ? "" : "."+posshalves[1])};
var intfmt = Regex.Replace(fmthalves[0], #"[0-9]", "#");
intfmt = Regex.Replace(intfmt, #"#+", "#");
var decfmt = Regex.Replace(fmthalves[1], "[0-9]", "0");
var format = $"{intfmt}{decfmt}";

How can I make phone numbers pretty/user friendly when their existing formats are inconsistent?

I'm binding a textbox to a member of a class, and I need to tweak the appearance of the phone number so that it's easier to read (the user doesn't want to see values such as "1234567890" or "+01234567890"). So, I've got this code:
var bindingPhone = new Binding("Text", platypusInfo, "Phone1", true);
bindingPhone.Format += phoneBinding_Format;
textBoxPhoneNum1.DataBindings.Add(bindingPhone);
...
private void phoneBinding_Format(object sender, ConvertEventArgs e) {
e.Value = ??How can I deal with this??
}
But the phone values, although usually either "NNNNNNNNNN" (such as "1234567890") or "+NNNNNNNNNNN" (such as "+01234567890") can also appear in a number of other permutations, such as:
(NN) NNNN NNNN
++NNNNNNNNNNNNN
+NNNNNNNNNNNNN
+NN NNNNNNNNNNN
NNNNNNNNNNNN
Is there anything I can do in phoneBinding_Format() that will make these phone numbers easier to read without breaking them into nonsensical parts, such as "43-4859-4365" instead of "434-859-4365"?
UPDATE
Due to these factors:
1) I'm working on several projects simultaneously and need to get back to another one
2) Our two most common formats comprise the lion's share of our phone numbers
3) This is just a "nice feature" not a "must-have" feature
...I've settled on the following for now, based on a Jon Skeet answer:
private void phoneBinding_Format(object sender, ConvertEventArgs e)
{
const int UK_PHONE_LEN = 9; // +NNNNNNNN
const int US_PHONE_FORMAT_LEN = 10; // NNNNNNNNNN
const int COMMON_INTERNATIONAL_FORMAT_LEN = 12; //+NNNNNNNNNNN
string phone;
string area;
string major;
string minor;
string intl_firstsegment;
string intl_secondsegment;
string intl_thirdsegment;
string intl_fourthsegment;
string intl_fifthsegment;
if (e.Value.ToString().Length == US_PHONE_FORMAT_LEN)
{
phone = e.Value.ToString();
area = phone.Substring(0, 3);
major = phone.Substring(3, 3);
minor = phone.Substring(6);
e.Value = string.Format("{0}-{1}-{2}", area, major, minor);
}
else if ((e.Value.ToString().Length == UK_PHONE_LEN) && (e.Value.ToString()[0] == '+')) {
phone = e.Value.ToString();
intl_firstsegment = phone.Substring(0, 2);
intl_secondsegment = phone.Substring(2, 3);
intl_thirdsegment = phone.Substring(5);
e.Value = string.Format("+{0}-{1}-{2}", intl_firstsegment, intl_secondsegment, intl_thirdsegment);
}
else if ((e.Value.ToString().Length == COMMON_INTERNATIONAL_PHONE_LEN) && (e.Value.ToString()[0] == '+'))
{
phone = e.Value.ToString();
intl_firstsegment = phone.Substring(0, 2);
intl_secondsegment = phone.Substring(2, 2);
intl_thirdsegment = phone.Substring(4, 3);
intl_fourthsegment = phone.Substring(7, 2);
intl_fifthsegment = phone.Substring(9);
e.Value = string.Format("+{0}-{1}-{2}-{3}-{4}", intl_firstsegment, intl_secondsegment, intl_thirdsegment, intl_fourthsegment, intl_fifthsegment);
}
}
BTW, an interesting thing happened on the way to breakpoint nirvana: I originally had these tests (1st character is a plus sign and length is the expected) reversed, and got: System.IndexOutOfRangeException was unhandled by user code
Message=Index was outside the bounds of the array.
Reversing the condition so that length was checked first (which naturally doesn't fail when length is 0/string is empty) fixed it (since then no attempt is made to access char 0).
Google's LibPhoneNumber could be just what you need if you want to support international phone numbers in addition to US (and Canadian, which are 100% compatible with US) numbers.
Google's common Java, C++ and Javascript library for parsing, formatting, storing and validating international phone numbers. The Java version is optimized for running on smartphones, and is used by the Android framework since 4.0 (Ice Cream Sandwich).
Using it from C#:
http://blog.thekieners.com/2011/06/06/using-googles-libphonenumber-in-microsoft-net-with-c/
C# port
https://bitbucket.org/pmezard/libphonenumber-csharp/wiki/Home
The easiest approach would be to just strip out all non-numeric characters and whitespace from the string before applying your formatting.
http://msdn.microsoft.com/en-us/library/844skk0h.aspx
Interesting code snippet here. Can be used to pretty-up phone numbers before displaying them.
Input: xxxxxxxxxx or xxx-xxx-xxxx or (xxx) xxx-xxxx, Output: (xxx) xxx-xxxx
Code:
private string formatPhoneNumber(string number) {
System.Text.RegularExpressions.Regex pattern = new System.Text.RegularExpressions.Regex("^\\(?([1-9]\\d{2})\\)?\\D*?([1-9]\\d{2})\\D*?(\\d{4})$");
Match re = Regex.Match(number, pattern.ToString());
return "(" + Convert.ToString(re.Groups[1]) + ") " + Convert.ToString(re.Groups[2]) + "-" + Convert.ToString(re.Groups[3]);
}
I would personally specify that only numeric phone numbers are allowed (meaning the user may not enter phone numbers like 1-800-FLOWERS) and then strip all non numeric characters, before formatting.
What I'm getting is that you have numbers stored in ten-digit character format ("1234567890"), without formatting, but now you need to add formatting to make the number more readable without making the number nonsensical for the country the number is used in. As different countries/regions have different default formats for numbers, the NANPA system of (ACD) COX-SUBS for area code, central office and subscriber doesn't always apply.
My suggestion would be to maintain a table or dictionary of phone number masks, then use a MaskedTextBox and bind not only the number, but the mask, to data in the contact object.
For instance, phone mask ID 1 might be for NANPA numbers: "000-000-0000". Phone mask ID 2 might be for London-metro numbers and would be "\000 0000 0000" (the leading digit is always a zero, and should be omitted when calling from outside the country). ID 3 might be for French phone numbers: "00 00 00 00 00". You can specify a "get-only" property on the object that will provide the actual mask string to the TextBox, and bind a different control (a drop-down maybe) that the user can choose to display the number in the correct format (which you can save for later use with that contact). Most of the time you'll be able to guess based on country, but this isn't always the case.
Understand that you will need a LOT of masks, and they aren't always ten digits. While the NANPA system is relatively consistent, UK phone numbers are a mess; geographic area codes are variable-length, and the total number can be ten or eleven digits, so there are six different masks just for UK numbers based on geographic area code. In Mexico, area codes can be two or three digits, and the total number is ten digits. French phone numbers are ten digits in groups of two. In addition, the actual combination of digits to be dialed depends on where you're calling from; if the call is always from the US, many European number systems drop their leading zero used for in-country calls and you instead dial the country code.

Categories