使用带有字符串数组的Regex数组

时间:2023-01-14 21:19:22

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".

假设我知道产品A始终以“C02”开头,产品B始终以“X02”结束,而产品C始终包含“A1700”。然后,如果用户输入为“C02HGV32,N93XA1700D,J3429X02”,则返回“C02HGV32:产品A; N93XA1700D:产品C; J3429X02:产品B”。

How would I get an array of Regex expressions to compare against the array of strings? Here's what I have:

我如何获得一组Regex表达式来与字符串数组进行比较?这就是我所拥有的:

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]
    }
}

3 个解决方案

#1


1  

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.

如果这些代码的要求如此简单,您可以使用String.Contains,String.StartsWith和String.EndsWith。您可以创建一个Dictionary来保存产品名称和函数,以检查给定的字符串是否具有产品的模式。

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:

如果您特别想使用Regex,可以使用以下模式:

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;
}

#2


1  

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:

现在你可以使用LINQ查询:

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

C02HGV32:产品A; N93XA1700D:产品C; J3429X02:产品B.

#3


0  

Regex syntax:

  • "^C02.*" - Starts with C02 followed by any number of characters including 0 characters.
  • “^ C02。*” - 以C02开头,后跟任意数量的字符,包括0个字符。

  • "^.*X02" - Starts with any number of characters including 0 characters and ends with X02.
  • “^。* X02” - 以任意数量的字符开头,包括0个字符,以X02结尾。

  • "^.A1700.*" - Starts and ends with any number of characters, and contains A1700 somewhere.

    “^ .A1700。*” - 以任意数量的字符开头和结尾,并在某处包含A1700。

    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


1  

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.

如果这些代码的要求如此简单,您可以使用String.Contains,String.StartsWith和String.EndsWith。您可以创建一个Dictionary来保存产品名称和函数,以检查给定的字符串是否具有产品的模式。

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:

如果您特别想使用Regex,可以使用以下模式:

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;
}

#2


1  

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:

现在你可以使用LINQ查询:

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

C02HGV32:产品A; N93XA1700D:产品C; J3429X02:产品B.

#3


0  

Regex syntax:

  • "^C02.*" - Starts with C02 followed by any number of characters including 0 characters.
  • “^ C02。*” - 以C02开头,后跟任意数量的字符,包括0个字符。

  • "^.*X02" - Starts with any number of characters including 0 characters and ends with X02.
  • “^。* X02” - 以任意数量的字符开头,包括0个字符,以X02结尾。

  • "^.A1700.*" - Starts and ends with any number of characters, and contains A1700 somewhere.

    “^ .A1700。*” - 以任意数量的字符开头和结尾,并在某处包含A1700。

    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();
    }