使用子字符串过滤字符串数组

Posted

技术标签:

【中文标题】使用子字符串过滤字符串数组【英文标题】:Filter string array with substring 【发布时间】:2021-06-06 20:03:50 【问题描述】:

所以我在一个数组中有这些值:

1_642-name.xml
1_642-name2.xml
1_678-name.xml
1_678-name2.xml

我总是只希望数字最大的值出现在我的数组中。但我似乎无法弄清楚如何?

字符串由以下因素组成:

1 是一个静态数字 - 永远只有 1

642 或 _ 和 - 之间的数字是一个恒等式,并且总是可以变大

name.xml 总是一样的

在这种情况下,我想按最大标识 (678) 进行过滤。

我试过这样的事情没有运气:

string[] filter = lines.FindAll(lines, x => x.Substring(3, 3));

结果:

1_678-name.xml
1_678-name2.xml

【问题讨论】:

每个字符串元素的格式是否总是相同的?您是否尝试过解析每个元素的不同部分?您的号码总是 3 位数吗? 您的问题含糊不清,请详细说明您拥有什么以及您想要什么 @gunr2171 是的,格式总是一样的,或者现在你说 - 中间数字 678 我猜也可以有 4 个数字.. 没想到 @TheGeneral 模糊的是什么?我解释说我总是想要数字最高的值? 每个字符串中有 2 或 3 个“数字”。使用软件,您可以更准确地了解您的要求(“您想通过哪个 number 订购”)是最好的。在这种情况下,您的意思是说“我只想返回集合中第一个“_”和第一个“-”之间的数字最大的条目。” 【参考方案1】:

因为您的格式中的字符数很容易变化,所以这对于正则表达式来说是一项很棒的工作。例如:

var input = "1_642-name2.xml";
var pattern = @"^\d+_(\d+)-.+$";
var match = Regex.Match(input, pattern);

match.Groups[1].Value; // "642" (as a string)

正则表达式字符串的解释可以在here找到。

我们可以使用它来提取数组中每个元素的各个部分。

首先要做的是找到最大值,如果我们有这种格式:

#_###-wordswords

然后我们想要_- 之间的数字。

var list = new string[]

    "1_642-name.xml",
    "1_642-name2.xml",
    "1_678-name.xml",
    "1_678-name2.xml"
;

var pattern = new Regex(@"^\d+_(\d+)-.+$");
var maxValue = list.Max(x => int.Parse(pattern.Match(x).Groups[1].Value));

这会找到“678”作为最大值。现在我们只需要过滤列表以仅显示该格式槽中具有“678”的条目。

var matchingEntries = list
    .Where(x => pattern.Match(x).Groups[1].Value == maxValue.ToString());

foreach (var entry in matchingEntries)

    Console.WriteLine(entry);

Where 使用您的最大值过滤列表。

这段代码有很多效率低下的地方。我正在对每个值进行两次正则表达式解析,并在每个元素上计算相当于 maxValue 的字符串。我将把修复这些作为练习留给读者。

【讨论】:

确保添加正确的 using 语句,例如 using System.Linq;using System.Text.RegularExpressions;。至于不清楚的地方,我只能推测原始帖子并不清楚您要订购的“数字”。我知道,从你的观点来看这是有道理的,但对于我们以前没有使用过你的代码的陌生人来说,这是模棱两可的。【参考方案2】:

只是为了提供正则表达式的替代方案,您还可以简单地解析每一行,检查数字,如果它是迄今为止我们发现的最大的,则将该行添加到列表中。每当找到更大的数字时清除列表,然后在最后返回列表。

一个好处是我们只循环遍历列表一次而不是两次:

public static List<string> GetHighestNumberedLines(List<string> input)

    if (input == null || !input.Any()) return input;

    var result = new List<string>();
    var highNum = int.MinValue;

    foreach (var line in input)
    
        var parts = line.Split('_', '-');
        int number;

        // Making sure we atually have a number where we expect it
        if (parts.Length > 1 && int.TryParse(parts[1], out number))
        
            // If this is the highest number we've found, update
            // our variable and reset the list to contain this line
            if (number > highNum)
            
                highNum = number;
                result = new List<string> line;
            
            // If this matches our high number, add this line to our list
            else if (number == highNum)
            
                result.Add(line);
            
        
    

    return result;

【讨论】:

以上是关于使用子字符串过滤字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

通过子字符串过滤或减少字符串数组

在 Mongoose/MongoDB 的文档中过滤数组、子文档、数组、文档

Arrays and -contains - 测试数组元素中的子字符串

Javascript通过包含搜索词的标签子数组过滤或减少每个JSON对象

一个衬里使用过滤器删除数组中所有出现的子串吗?

根据字符串数组过滤对象数组