check for valid string format - c#

i am trying to make a validaing system where it checks a string is in the correct format.
the required format can only contain numbers and dashes - and be ordered like so ***-**-*****-**-* 3-2-5-2-1.
For example, 978-14-08855-65-2
can i use Regex like i have for a email checking system by change the format key #"^([\w]+)#([\w])\.([\w]+)$"
the email checking code is
public static bool ValidEmail(string email, out string error)
{
error = "";
string regexEmailCOM = #"^([\w]+)#([\w])\.([\w]+)$"; // allows for .com emails
string regexEmailCoUK = #"^([\w]+)#([\w])\.([\w]+)\.([\w]+)$"; // this allows fo .co.uk emails
var validEmail = new Regex(email);
return validEmail.IsMatch(regexEmailCOM) || validEmail.IsMatch(regexEmailCoUK) && error == "") // if the new instance matches with the string, and there is no error
}

Regex is indeed a good fit for this situation.
One possible expression would be:
^\d{3}-\d\d-\d{5}-\d\d-\d$
This matches exactly 5 groups of only digits (\d) separated by -. Use curly brackets to set a fixed number of repeats.

Related

C# validate input syntax and replace values

I am trying to make a function that validates an input string format and then replaces some values. The string should contain data in the following format:
string data = "'({today} - ({date1} + {date2}))', 'user', 'info'";
I want to make sure that the string is typed in the above format format(validate it), and if it is to replace the values of today, date1 and date2 with some values.
I am thinking of something like that, but I don't know if that is the best way:
if (data.Contains("{today}") && data.Contains("{date1}") && data.Contains("{date2}"))
{ }
Anybody can suggest something?
Here is what you asked, if I understood your comment correctly.
string data = "'({today} - ({date1} + {date2}))', 'user', 'info'"; // your string
string pattern = #"\{.*?\}"; // pattern that will match everything in format {anything}
Regex regEx = new Regex(pattern); //create regex using pattern
MatchCollection matches; // create collection of matches
matches = regEx.Matches(data); // get all matches from your string using regex
for (int i = 0; i < matches.Count; i++) // use this cycle to check if it s what you need
{
Console.WriteLine("{0}", matches[i].Value);
}
To validate your string, what you have suggested is fine. You could make it easier by checking for the negative:
if(!myString.Contains("{today}")
// handle error
if(!myString.Contains("{date1}")
// handle error
In order to replace the values, you can use String.Replace(...).
var myReplacedValue = myString.Replace("{today}", valueToRepalceWith);

C# - How to format datetime to remove trailing zeros

I'm setting up an orchestration class that handles multiple actions as one big transaction. For each of these transactions I give them the same time-stamp instantiated at the beginning of the orchestration.
I user the following line:
var transactionTimestamp = DateTime.UtcNow.ToString("o");
I have a constraint in the system that dictates that the time stamp cannot have any trailing zeros.
For example:
2013-06-26T19:51:38.0083980Z //bad
2013-06-26T19:51:38.008398Z //good
2013-06-26T19:51:38.0083988Z //good
The built-in DateTime format "o" is comparable to the custom format of: "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffffffK". If you just use that format, but replace the lower-case f's with upper case ones, there will be no trailing zeros.
ie
DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'FFFFFFFK");
Custom date and time format strings
You can achieve this fairly easily using Regex. Here's one way.
string result = Regex.Replace("2013-06-26T19:51:38.0083980Z", "0+Z$", "Z");
// result == "2013-06-26T19:51:38.008398Z"
string result2 = Regex.Replace("2013-06-26T19:51:38.0083988Z", "0+Z$", "Z")
// result2 == "2013-06-26T19:51:38.0083988Z"
I would write my own help method like;
public string GetDtString(DateTime dt)
{
RegEx rgx = new RegEx("[1-9]0+Z\b");
return rgx.Replace(dt.ToString("o"), System.String.Empty);
}
It basically just returns the dt string with all 0's which occur after a digit 1-9 and before Z\b (Z followed by a word boundary) with an empty string.

Replace part of a string with new value

I've got a scenario, wherein i need to replace the string literal with new text.
For example, if my string is "01HW128120", i will first check if the text contains "01HW" If yes, then replace that with the string "MachineID-".
So eventually i wanted "01HW128120" to be "MachineID-128120". Sometimes i do get the string as "1001HW128120" - In this case also i require to replace the "1001HW" with "MachineID-"
I tried the below code snippet, but this does not work to my expectation.
string sampleText = "01HW128120";
if(sampleText.Contains("01HW"))
sampleText = sampleText.Replace("01HW","MachineID-");
Any suggestion would be of great help to me.
Few Possible Search Values
If there are only a few possible combinations, you can simply do multiple tests:
string value = "01HW128120";
string replacement = "MachineID-";
if( value.Contains( "01HW" ) ) {
value = value.Replace( "01HW", replacement );
}
else if( value.Contains( "1001HW" ) ) {
value = value.Replace( "1001HW", replacement );
}
Assert.AreEqual( "MachineID-128120", value );
Many Possible Search Values
Of course, this approach quickly becomes unwieldy if you have a large quantity of possibilities. Another approach is to keep all of the search strings in a list.
string value = "01HW128120";
string replacement = "MachineID-";
var tokens = new List<string> {
"01HW",
"1001HW"
// n number of potential search strings here
};
foreach( string token in tokens ) {
if( value.Contains( token ) ) {
value = value.Replace( token, replacement );
break;
}
}
"Smarter" Matching
A regular expression is well-suited for string replacement if you have a manageable number of search strings but you perhaps need not-exact matches, case-insensitivity, lookaround, or capturing of values to insert into the replaced string.
An extremely simple regex which meets your stated requirements: 1001HW|01HW.
Demo: http://regexr.com?34djm
A slightly smarter regex: ^\d{2,4}HW
Assert position at start of string
Match 2-4 digits
Match the value "HW" literally
See also: Regex.Replace Method
If you just want to replace everything up to "01HW" with "MachineID-", you could use a generic regex:
sampleText = Regex.Replace(sampleText, "^.*01HW", "MachineID-");

C# Regex.Match to decimal

I have a string "-4.00 %" which I need to convert to a decimal so that I can declare it as a variable and use it later. The string itself is found in string[] rows. My code is as follows:
foreach (string[] row in rows)
{
string row1 = row[0].ToString();
Match rownum = Regex.Match(row1.ToString(), #"\-?\d+\.+?\d+[^%]");
string act = Convert.ToString(rownum); //wouldn't convert match to decimal
decimal actual = Convert.ToDecimal(act);
textBox1.Text = (actual.ToString());
}
This results in "Input string was not in a correct format." Any ideas?
Thanks.
I see two things happening here that could contribute.
You are treating the Regex Match as though you expect it to be a string, but what a Match retrieves is a MatchGroup.
Rather than converting rownum to a string, you need to lookat rownum.Groups[0].
Secondly, you have no parenthesised match to capture. #"(\-?\d+\.+?\d+)%" will create a capture group from the whole lot. This may not matter, I don't know how C# behaves in this circumstance exactly, but if you start stretching your regexes you will want to use bracketed capture groups so you might as well start as you want to go on.
Here's a modified version of your code that changes the regex to use a capturing group and explicitly look for a %. As a consequence, this also simplifies the parsing to decimal (no longer need an intermediary string):
EDIT : check rownum.Success as per executor's suggestion in comments
string[] rows = new [] {"abc -4.01%", "def 6.45%", "monkey" };
foreach (string row in rows)
{
//regex captures number but not %
Match rownum = Regex.Match(row.ToString(), #"(\-?\d+\.+?\d+)%");
//check for match
if(!rownum.Success) continue;
//get value of first (and only) capture
string capture = rownum.Groups[1].Value;
//convert to decimal
decimal actual = decimal.Parse(capture);
//TODO: do something with actual
}
If you're going to use the Match class to handle this, then you have to access the Match.Groups property to get the collection of matches. This class assumes that more than one occurrence appears. If you can guarantee that you'll always get 1 and only 1 you could get it with:
string act = rownum.Groups[0];
Otherwise you'll need to parse through it as in the MSDN documentation.

parsing a string into int/long using custom format strings

In C#.Net, here's a simple example of how to format numbers into strings using custom format strings:
(example taken from: http://www.csharp-examples.net/string-format-int/)
String.Format("{0:+### ### ### ###}", 447900123456); // "+447 900 123 456"
String.Format("{0:##-####-####}", 8958712551); // "89-5871-2551"
Is there a way to convert this formatted string back into a long/integer ? Is there someway to do this :
long PhoneNumber = Int32.Parse("89-5871-2551", "{0:##-####-####}");
I saw that DateTime has a method ParseExact which can do this work well. But I did not see any such thing for int/long/decimal/double.
You can regex out all of the non numeric numbers, and what you're left with is a string of numbers that you can parse.
var myPhoneNumber = "89-5871-2551";
var strippedPhoneNumber = Regex.Replace(myPhoneNumber, #"[^\d]", "");
int intRepresentation;
if (Int32.TryParse(strippedPhoneNumber, out intRepresentation))
{
// It was assigned, intRepresentation = 8958712551
// now you can use intRepresentation.
} else {
// It was not assigned, intRepresentation is still null.
}
Well, you can always do
long PhoneNumber = Int32.Parse("89-5871-2551".
Replace(new char[]{'-','+',whatever..}).Trim());
By the way, considering that you're parsing a string received from some IO, I would suggest to use more secure (in terms of conversion) Int32.TryParse method.
The way like you described doesn't actually exist.
Just Regex out all of the non-numeric characters, then parse that string.

Categories