I'm trying to make a program where a user can input an array of serial numbers and have each corresponding product show up.
Suppose I know that Product A always starts with "C02", Product B always ends in "X02", and Product C always contains "A1700". Then if the user input was "C02HGV32,N93XA1700D,J3429X02", it would return "C02HGV32: Product A; N93XA1700D: Product C; J3429X02: Product B".
How would I get an array of Regex expressions to compare against the array of strings? Here's what I have:
using System.Text.RegularExpressions;
public class ReturnProduct{
public Regex[] compareAgainst = new Regex[3]{@"[C02]*",@"*[X02]",@"*[A1700]*"}; //Clearly not the right way, but not sure how else to do it
...
public string getTheProduct(string input){
string[] compareString = input.Split(",");
for (int a = 0; a < compareString.Length; a++){
for (int b = 0; b < compareAgainst.Length; b++){
//Do something Regex-y with compareString[a] and compareAgainst[b]
}
}
-
Are you asking for the correct Regex syntax? Or how to check if a string matches a regex?Blorgbeard– Blorgbeard2017年08月08日 17:08:36 +00:00Commented Aug 8, 2017 at 17:08
-
I'm asking both the correct syntax for a Regex array, and how to check each string value against each Regex array value - sorry about the clarity.user4518077– user45180772017年08月08日 17:20:23 +00:00Commented Aug 8, 2017 at 17:20
-
I didn't downvote, but "How exactly would this work?" is not exactly a clear question. I wouldn't assume that you were downvoted for "trying to explain as much as possible".Blorgbeard– Blorgbeard2017年08月08日 19:34:52 +00:00Commented Aug 8, 2017 at 19:34
-
I guess I should have used a semicolon for that - the "How exactly would this work?" was relating to the previous sentence. Bad English. I've updated it now.user4518077– user45180772017年08月08日 19:38:36 +00:00Commented Aug 8, 2017 at 19:38
3 Answers 3
If the requirements of these codes are so simple you can use String.Contains, String.StartsWith and String.EndsWith. You can create a Dictionary to hold product names and functions to check if a given string has the pattern for a product.
var dict = new Dictionary<string, Predicate<string>>
{
["Product A"] = s => s.StartsWith("C02"),
["Product B"] = s => s.EndsWith("X02"),
["Product C"] = s => s.Contains("A1700")
};
string GetProductName(string serialNum)
{
foreach(var keyVal in dict)
{
if(keyVal.Value(serialNum))
return keyVal.Key;
}
return "No product name found";
}
List<(string, string)> GetProductNames(string str)
{
var productCodes = str.Split(',');
var productNames = new List<(string, string)>(); // list of tuples (string, string)
foreach(var serialNum in productCodes)
{
productNames.Add((serialNum, GetProductName(serialNum)));
}
return productNames;
}
Usage:
var userString = "C02HGV32,N93XA1700D,J3429X02";
List<(string serialNum, string name)> productNames = GetProductNames(userString);
foreach(var tuple in productNames)
{
Console.WriteLine($"{tuple.serialNum} : {tuple.name}");
}
If you specifically want to use Regex, you can use the following patterns:
var regexDict = new Dictionary<string, Regex>
{
["Product A"] = new Regex("^C02"), //'^' means beginning of string
["Product B"] = new Regex("X02$"), //'$' means end of string
["Product C"] = new Regex("A1700") //given string anywhere
};
string GetProductName(string serialNum)
{
foreach(var keyVal in regexDict)
{
if(keyVal.Value.IsMatch(serialNum))
return keyVal.Key;
}
return "No product name found";
}
List<(string, string)> GetProductNames(string str)
{
var productCodes = str.Split(',');
var productNames = new List<string>();
foreach(var serialNum in productCodes)
{
productNames.Add((serialNum, GetProductName(serialNum)));
}
return productNames;
}
5 Comments
Define a class for your products:
public class Product
{
public string Name { get; set; }
public Regex Expr { get; set; }
}
then create an array with all your regexes:
var regexes = new[]
{
new Product
{
Name = "Product A",
Expr = new Regex("^C02")
},
new Product
{
Name = "Product B",
Expr = new Regex("X02$")
},
new Product
{
Name = "Product C",
Expr = new Regex("A1700")
}
};
now you can use LINQ query:
var input = "C02HGV32,N93XA1700D,J3429X02";
var result = string.Join("; ",
input.Split(',')
.Select(s => new {regexes.FirstOrDefault(p => p.Expr.IsMatch(s))?.Name, Value = s})
.Select(x => $"{x.Value}: {x.Name}"));
result would be
C02HGV32: Product A; N93XA1700D: Product C; J3429X02: Product B
Comments
Regex syntax:
- "^C02.*" - Starts with C02 followed by any number of characters including 0 characters.
- "^.*X02" - Starts with any number of characters including 0 characters and ends with X02.
"^.A1700.*" - Starts and ends with any number of characters, and contains A1700 somewhere.
public static void GetTheProduct(string input, List<Regex> regList) { List<string> compareString = input.Split(new char[] { ',' }).ToList(); foreach (string item in compareString) { if (regList[0].Match(item).Success) Console.WriteLine("{0} : {1}", item, "Product A"); else if (regList[1].Match(item).Success) Console.WriteLine("{0} : {1}", item, "Product B"); else if (regList[2].Match(item).Success) Console.WriteLine("{0} : {1}", item, "Product C"); } } static void Main(string[] args) { List<Regex> regexList = new List<Regex>() { new Regex("^C02.*"), new Regex("^.*X02"), new Regex("^.*A1700.*") }; GetTheProduct("C02HGV32,N93XA1700D,J3429X02", regexList); Console.ReadLine(); }
You could also generalize the method and avoid hardcoding Product names. Like so:
public static void GetTheProduct(string input, Dictionary<string, Regex> regDictionary)
{
List<string> compareString = input.Split(new char[] { ',' }).ToList();
foreach (string item in compareString)
{
string key = regDictionary.First(x => x.Value.IsMatch(item)).Key;
Console.WriteLine("{0} : {1}", item, key);
}
}
static void Main(string[] args)
{
Dictionary<string, Regex> regDictionary = new Dictionary<string, Regex>();
regDictionary.Add("Product A", new Regex("^C02.*"));
regDictionary.Add("Product B", new Regex("^.*X02"));
regDictionary.Add("Product C", new Regex("^.*A1700.*"));
GetTheProduct("C02HGV32,N93XA1700D,J3429X02", regDictionary);
Console.ReadLine();
}
1 Comment
^.*X02 doesn't mean ends with anything. No reason to overkill the match as Regex searches for a match inside the string by default: A1700 is sufficient for contains "A1700". ^C02 is sufficient for begins with "C02".