从字符串列表中提取索引号

时间:2019-08-15 14:44:50

标签: c# regex

我有一个字符串列表,这些字符串在每个字符串中都有一个索引,我需要从该字符串中提取索引并将其放在List<int>中。

这是一个列表示例:

List<string> values = new List<string>();
values.Add("cohabitantGender");
values.Add("additionalDriver0LastName");
values.Add("additionalDriver0AgeWhenLicensed");
values.Add("vehicle0City");
values.Add("vehicle1City");
values.Add("vehicle2City");
values.Add("vehicle3City");

从该列表中,我需要从值vehicleXCity中提取索引。 我现在有以下代码:

public static List<int> FormObjectIndexExtractor(List<string> values, string prefix, string suffix)
{
    var selectedMatches = values.Where(v => v.StartsWith(prefix) && v.EndsWith(suffix)).Select(v=> v).ToList();
    var indexes = new List<int>();
    foreach (var v in selectedMatches) indexes.Add(int.Parse(Regex.Match(v, @"\d+").Value));
    return indexes;
}

我正在这样使用它:

List<int> indexes = FormObjectIndexExtractor(values, "vehicle", "City");

但是,如果我有一个类似vehicle4AnotherCity的值,则代码将以错误的方式工作。

有人可以替代此代码吗?

5 个答案:

答案 0 :(得分:1)

下面是扩展帮助程序类,以防您拥有更强大的列表并且需要多个排除选项

public class INumberList : List<string>
{ 
    public List<int> GetNumberList()
    {
        List<int> numberList = new List<int>();
        for (int i = 0; i < this.Count; i++)
        {
            numberList.Add(GetIntFromString(this[i]));
        }
        return numberList;
    } 
    public INumberList ExcludeIndex(string prefix, string suffix)
    {
        for (int i = 0; i < this.Count; i++)
        { 
            if (this[i].StartsWith(prefix) && this[i].EndsWith(suffix))
            {
                //remove non needed indexes
                this.RemoveAt(i);
            }
        }
        return this;
    }
    public static int GetIntFromString(String input)
    {
        // Replace everything that is no a digit.
        String inputCleaned = Regex.Replace(input, "[^0-9]", "");

        int value = 0;

        // Tries to parse the int, returns false on failure.
        if (int.TryParse(inputCleaned, out value))
        {
            // The result from parsing can be safely returned.
            return value;
        }

        return 0; // Or any other default value.
    }
}

然后这样使用:

INumberList values = new INumberList();
        values.Add("cohabitantGender");
        values.Add("additionalDriver0LastName");
        values.Add("additionalDriver0AgeWhenLicensed");
        values.Add("vehicle0City");
        values.Add("vehicle1City");
        values.Add("vehicle2City");
        values.Add("vehicle3City");
//Get filtered index list with multiple exclusion option
List<int> indexList = values.ExcludeIndex("cohabitantGender","")
                        .ExcludeIndex("additionalDriver","AgeWhenLicensed")
                        .GetNumberList(); 
//will return [0,0,1,2,3]

答案 1 :(得分:0)

这是不使用Regex的解决方案(使用现代C#功能):

public static List<int> FormObjectIndexExtractor(IEnumerable<string> values, string prefix, string suffix)
{
  int? TryParseItem(string val)
  {
    if (val.Length <= prefix.Length + suffix.Length || !val.StartsWith(prefix) || !val.EndsWith(suffix))
      return null;

    var subStr = val.Substring(prefix.Length, val.Length - prefix.Length - suffix.Length);

    if (int.TryParse(subStr, out var number))
      return number;

    return null;
  }

  return values.Select(TryParseItem).Where(v => v.HasValue).Select(v => v.Value).ToList();
}

答案 2 :(得分:0)

尝试一下:

private static final int START = 1;
private static final int END = 67;
private List<JMenuItem> list;


private void initializeList(){

   /*You will need the convertIntToSpelledString(int) method
    *as @Andy Thomas mentioned above in his comment
    */

   this.list = IntStream.rangeClosed(START, END).boxed()
                        .map(i -> new JMenuItem(convertIntToSpelledString(i))
                        .collect(Collectors.toList());
}


答案 3 :(得分:-1)

此版本拆分字符串的所有部分。

public static List<int> FormObjectIndexExtractor(List<string> values, string prefix, string suffix)
{
    List<int> ret = new List<int>();
    Regex r = new Regex("^([a-zA-Z]+)(\\d+)([a-zA-Z]+)$");
    foreach (var s in values)
    {
        var match = r.Match(s);
        if (match.Success)
        {
            if (match.Groups[1].ToString() == prefix && match.Groups[3].ToString() == suffix)
            {
                ret.Add(int.Parse(match.Groups[2].ToString()));
            }
        }
    }
    return ret;
}

或者:

public static List<int> FormObjectIndexExtractor(List<string> values, string prefix, string suffix)
{
    List<int> ret = new List<int>();
    Regex r = new Regex($"^{prefix}(\d+){suffix}$");
    foreach (var s in values)
    {
        var match = r.Match(s);
        if (match.Success)
        {
            ret.Add(int.Parse(match.Groups[1].ToString()));
        }
    }
    return ret;
}

答案 4 :(得分:-2)

这是更通用的版本。

  1. 正则表达式匹配:

    • 以“车辆”开头
    • 匹配数字
    • 以'city'结尾。
  2. 解析并返回为List<int>

        var indexes = values.Where(a => Regex.IsMatch(a, @"^vehicle\d+City$")).
                              Select(k => int.Parse(Regex.Match(k, @"\d+").Value)).ToList();