使用子字符串过滤字符串数组
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 - 测试数组元素中的子字符串