string macro replacement - c#

I have a Visual Studio 2008 C# .NET 3.5 application where I need to parse a macro.
Given a serial serial number that is N digits long, and a macro like %SERIALNUMBER3%, I would like this parse method to return only the first 3 digits of the serial number.
string serialnumber = "123456789";
string macro = "%SERIALNUMBER3%";
string parsed = SomeParseMethod(serialnumber, macro);
parsed = "123"
Given `%SERIALNUMBER7%, return the first 7 digits, etc..
I can do this using String.IndexOf and some complexity, but I wondered if there was a simple method. Maybe using a Regex replace.
What's the simplest method of doing this?

var str = "%SERIALNUMBER3%";
var reg = new Regex(#"%(\w+)(\d+)%");
var match = reg.Match( str );
if( match.Success )
{
string token = match.Groups[1].Value;
int numDigits = int.Parse( match.Groups[2].Value );
}

Use the Regex class. Your expression will be something like:
#"%(\w)+(\d)%"
Your first capture group is the ID (in this case, "SERIALNUMBER"), and your second capture group is the number of digits (in this case, "3").

Very quick and dirty example:
static void Main(string[] args)
{
string serialnumber = "123456789";
string macro = "%SERIALNUMBER3%";
var match = Regex.Match(macro, #"\d+");
string parsed = serialnumber.Substring(0, int.Parse(match.ToString()));
}

Related

Regex to extract specific numbers in a String

string temp = "12345&refere?X=Assess9677125?Folder_id=35478";
I need to extract the number 12345 alone and I don't need the numbers 9677125 and 35478.
What regex can I use?
Here is the regex for extracting 5 digit number in the beginning of the string:
^(\d{5})&
If length is arbitrary:
^(\d+)&
If termination pattern is not always &:
^(\d+)[^\d]
Based on the Sayse's comment you can simply rewrite as:
^(\d+)
and in case of the termination is some number(for instance 999) then:
^(\d+)999
You don't need regex if you only want to extract the first number:
string temp = "12345&refere?X=Assess9677125?Folder_id=35478";
int first = Int32.Parse(String.Join("", temp.TakeWhile(c => Char.IsDigit(c))));
Console.WriteLine(first); // 12345
If the number you want is always at the beginning of the string and terminated by an ampersand (&) you don't need a regex at all. Just split the string on the ampersand and get the first element of the resulting array:
String temp = "12345&refere?X=Assess9677125?Folder_id=35478";
var splitArray = String.Split('&', temp);
var number = splitArray[0]; // returns 12345
Alternatively, you can get the index of the ampersand and substring up to that point:
String temp = "12345&refere?X=Assess9677125?Folder_id=35478";
var ampersandIndex = temp.IndexOf("&");
var number = temp.SubString(0, ampersandIndex); // returns 12345
From what you haven given us this is fairly simple:
var regex = new Regex(#"^(?<number>\d+)&");
var match = regex.Match("12345&refere?X=Assess9677125?Folder_id=35478");
if (match.Success)
{
var number = int.Parse(match.Groups["number"].Value);
}
Edit: Of course you can replace the argument of new Regex with any of the combinations Giorgi has given.

c# trying to change first letter to uppercase but doesn't work

I have to convert the first letter of every word the user inputs into uppercase. I don't think I'm doing it right so it doesn't work but I'm not sure where has gone wrong D: Thank you in advance for your help! ^^
static void Main(string[] args)
{
Console.Write("Enter anything: ");
string x = Console.ReadLine();
string pattern = "^";
Regex expression = new Regex(pattern);
var regexp = new System.Text.RegularExpressions.Regex(pattern);
Match result = expression.Match(x);
Console.WriteLine(x);
foreach(var match in x)
{
Console.Write(match);
}
Console.WriteLine();
}
If your exercise isn't regex operations, there are built-in utilities to do what you are asking:
System.Globalization.TextInfo ti = System.Globalization.CultureInfo.CurrentCulture.TextInfo;
string titleString = ti.ToTitleCase("this string will be title cased");
Console.WriteLine(titleString);
Prints:
This String Will Be Title Cased
If you operation is for regex, see this previous StackOverflow answer: Sublime Text: Regex to convert Uppercase to Title Case?
First of all, your Regex "^" matches the start of a line. If you need to match each word in a multi-word line, you'll need a different Regex, e.g. "[A-Za-z]".
You're also not doing anything to actually change the first letter to upper case. Note that strings in C# are immutable (they cannot be changed after creation), so you will need to create a new string which consists of the first letter of the original string, upper cased, followed by the rest of the string. Give that part a try on your own. If you have trouble, post a new question with your attempt.
string pattern = "(?:^|(?<= ))(.)"
^ doesnt capture anything by itself.You can replace by uppercase letters by applying function to $1.See demo.
https://regex101.com/r/uE3cC4/29
I would approach this using Model Extensions.
PHP has a nice method called ucfirst.
So I translated that into C#
public static string UcFirst(this string s)
{
var stringArr = s.ToCharArray(0, s.Length);
var char1ToUpper = char.Parse(stringArr[0]
.ToString()
.ToUpper());
stringArr[0] = char1ToUpper;
return string.Join("", stringArr);
}
Usage:
[Test]
public void UcFirst()
{
string s = "john";
s = s.UcFirst();
Assert.AreEqual("John", s);
}
Obviously you would still have to split your sentence into a list and call UcFirst for each item in the list.
Google C# Model Extensions if you need help with what is going on.
One more way to do it with regex:
string input = "this string will be title cased, even if there are.cases.like.that";
string output = Regex.Replace(input, #"(?<!\w)\w", m => m.Value.ToUpper());
I hope this may help
public static string CapsFirstLetter(string inputValue)
{
char[] values = new char[inputValue.Length];
int count = 0;
foreach (char f in inputValue){
if (count == 0){
values[count] = Convert.ToChar(f.ToString().ToUpper());
}
else{
values[count] = f;
}
count++;
}
return new string(values);
}

Find an integer value inside a string

I'm looking to find the integer value inside the following string:
"value="5412304756756756756756792114343986"
How can I do this using C#?
You can use a regex to find the number in a string:
var resultString = Regex.Match(subjectString, #"\d+").Value;
For negative values:
var resultString = Regex.Match(yourString, #"(|-)\d+").Value;
You can look for the equals sign...
string yourString = "value=5412304756756756756756792114343986";
string integerPart = yourString.Split('=')[1];
You can use char.IsDigit
Something like .
string str = "value=5412304756756756756756792114343986";
List<char> justDigits = new List<char>();
foreach(char c in str)
{
if (char.IsDigit(c))
justDigits.Add(c);
}
string intValues = new string(justDigits.ToArray());
Or Shorter version
string intValues = new string(str.Where(char.IsDigit).ToArray());
You can use Regex:
int IntVal = Int32.Parse(Regex.Match(yourString, #"(|-)\d+").Value);
This will match negative numbers too. You could also iterate over every character in string and check id they are numerical but not really desirable solution because it can be a bottleneck.
Edit: In your input number is larger than long. For numbers like this, you can use BigInteger, from framework 4.0 onwards
Match match = new Regex("[0-9]+").Match("value=\"5412304756756756756756792114343986\"");
while(match.Success)
{
// Do something
match = match.NextMatch();
}

indexof exactvalue match

environment: microsoft visual studio 2008 c#
How do I get the index of a whole word found in a string
string dateStringsToValidate = "birthdatecake||birthdate||other||strings";
string testValue = "birthdate";
var result = dateStringsToValidate.IndexOf(testValue);
It doesn't have to be the way i did it either, for example, would it be better to use regular expressions or other methods?
Update:
The word is birthdate not birthdatecake. it doesn't have to retrieve the match but the index should find the right word. i don't think IndexOf is what i'm looking for then. Sorry for being unclear.
Use regular expressions for this
string dateStringsToValidate = "birthdatecake||birthdate||other||strings";
string testValue = "strings";
var result = WholeWordIndexOf(dateStringsToValidate, testValue);
// ...
public int WholeWordIndexOf(string source, string word, bool ignoreCase = false)
{
string testValue = "\\W?(" + word + ")\\W?";
var regex = new Regex(testValue, ignoreCase ?
RegexOptions.IgnoreCase :
RegexOptions.None);
var match = regex.Match(source);
return match.Captures.Count == 0 ? -1 : match.Groups[0].Index;
}
Learn more about regex options in c# here
Another option, depending on your needs, is to split the string (as I see you have some delimiters). Please note the index returned by the this option is the index by word count, not character count (In this case, 1, as C# has zero based arrays).
string dateStringsToValidate = "birthdatecake||birthdate||other||strings";
var split = dateStringsToValidate.Split(new string[] { "||" }, StringSplitOptions.RemoveEmptyEntries);
string testValue = "birthdate";
var result = split.ToList().IndexOf(testValue);
If you must deal with the exact index in the given string, then this is of little use to you. If you just want to find the best match in the string, this could work for you.
var dateStringsToValidate = "birthdatecake||birthdate||other||strings";
var toFind = "birthdate";
var splitDateStrings = dateStringsToValidate.Split(new[] {"||"}, StringSplitOptions.None);
var best = splitDateStrings
.Where(s => s.Contains(toFind))
.OrderBy(s => s.Length*1.0/toFind.Length) // a metric to define "best match"
.FirstOrDefault();
Console.WriteLine(best);

String parsing, extracting numbers and letters

What's the easiest way to parse a string and extract a number and a letter? I have string that can be in the following format (number|letter or letter|number), i.e "10A", "B5", "C10", "1G", etc.
I need to extract the 2 parts, i.e. "10A" -> "10" and "A".
Update: Thanks to everyone for all the excellent answers
Easiest way is probably to use regular expressions.
((?<number>\d+)(?<letter>[a-zA-Z])|(?<letter>[a-zA-Z])(?<number>\d+))
You can then match it with your string and extract the value from the groups.
Match match = regex.Match("10A");
string letter = match.Groups["letter"].Value;
int number = int.Parse(match.Groups["number"].Value);
The easiest and fastest is to use simple string operations. Use the IsDigit method to check where the letter is, and parse the rest of the string to a number:
char letter = str[0];
int index = 1;
if (Char.IsDigit(letter)) {
letter = str[str.Length - 1];
index = 0;
}
int number = int.Parse(str.Substring(index, str.Length - 1));
Just to be different:
string number = input.Trim("ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray());
string letter = input.Trim("0123456789".ToCharArray());
char letter = str.Single(c => char.IsLetter(c));
int num = int.Parse(new string(str.Where(c => char.IsDigit(c)).ToArray()));
This solution is not terribly strict (it would allow things like "5A2" and return 'A' and 52) but it may be fine for your purposes.
Here is how I would approach this. You can step through this and put gc1["letter"], gc1["number"], gc2["letter"], and gc2["number"] in the watch window to see that it worked (step just past the last line of code here, of course).
The regular epxression will take either pattern requiring one or more letter and number in each case.
Regex pattern = new Regex("^(?<letter>[a-zA-Z]+)(?<number>[0-9]+)|(?<number>[0-9]+)(?<letter>[a-zA-Z]+)$");
string s1 = "12A";
string s2 = "B45";
Match m1 = pattern.Match(s1);
Match m2 = pattern.Match(s2);
GroupCollection gc1 = m1.Groups;
GroupCollection gc2 = m2.Groups;
Using Sprache and some Linq kung-fu:
var tagParser =
from a in Parse.Number.Or(Parse.Letter.Once().Text())
from b in Parse.Letter.Once().Text().Or(Parse.Number)
select char.IsDigit(a[0]) ?
new{Number=a, Letter=b} : new{Number=b, Letter=a};
var tag1 = tagParser.Parse("10A");
var tag2 = tagParser.Parse("A10");
tag1.Letter; // should be A
tag1.Number; // should be 10
tag2.Letter; // should be A
tag2.Number; // should be 10
/* Output:
A
10
A
10
*/

Categories