首页 > 解决方案 > C# 将两个字符串列表与一个模式相交

问题描述

我有两个这样的字符串列表:

var entities= new List<string>(){"101", "102", "103",}; 
var files= new List<string>(){"101_F05_20101001.csv", "102_F05_20101001.csv", "201_F05_20101001.csv", "202_F05_20101001.csv"};

我想得到按照这种模式将它们相交的结果:

ID_F05_YYYYMMDD.csv

其中 ID 应匹配实体列表中的一项或多项。

我写了以下代码:

var list = files
    .Where(x => entities.Any(y => x.Contains(y) && x.Substring(0, y.Length) == y))
    .ToList();

在这里运行代码。

但我想知道是否可以使用像这样的正则表达式来改进这一点:

var regex = new Regex(@"^(\d*)_F05_\d*\.csv$");

可能吗?

标签: c#regexlistintersection

解决方案


您可以使用

.Where(x => Regex.IsMatch(x, $@"^(?:{string.Join("|", entities)})_F05_\d*\.csv$"))

正则表达式看起来像^(?:101|102|103)_F05_\d*\.csv$给定您当前的输入数据,它会匹配

  • ^- 字符串的开始
  • (?:101|102|103)- 匹配的非捕获组101102103
  • _F05_- 文字字符串
  • \d*- 0 位或更多位
  • \.csv-.csv字符串
  • $- 字符串结束

entities请注意,如果它们是数字,则不需要正则表达式转义。否则,您需要使用string.Join("|", entities.Select(Regex.Escape)).

C# 代码演示

var entities= new List<string>(){"101", "102", "103",}; 
var files= new List<string>(){"101_F05_20101001.csv", "102_F05_20101001.csv", "201_F05_20101001.csv", "202_F05_20101001.csv"};

var pat = $@"^(?:{string.Join("|", entities)})_F05_\d*\.csv$";

var list = files
        .Where(x => Regex.IsMatch(x, pat))
        .ToList();

foreach (var s in list) {
    Console.WriteLine(s);
}

输出:

101_F05_20101001.csv
102_F05_20101001.csv

推荐阅读