在文本文件中更智能地读取'

本文关键字:读取 智能 文本 文件 | 更新日期: 2023-09-27 18:05:22

我有一个文本文件,其中包含一个按字母顺序组织的变量列表,旁边是它们的变量编号,格式如下:

aabcdef           208
abcdefghijk       1191
bcdefga           7
cdefgab           12
defgab            100
efgabcd           999
fgabc             86
gabcdef           9
h                 11
ijk               80
...
...

我想读取每个文本作为一个字符串,并保持它的指定id#像读取"aabcdef",并将其存储到一个数组在点208。

我遇到的两个问题是:

  1. 我从来没有在c#中读取过文件,有没有一种方法可以读取,比如从作为字符串的行开始为空白?然后下一个字符串是一个整型直到行尾?

  2. 考虑到这些文件的性质和大小,我不知道每个文件的最高ID值(不是所有的数字都被使用,所以有些)文件可以容纳3000这样的数字,但实际上只列出200那么我怎样才能灵活地存储这些变量呢变量时,我不知道数组/列表/堆栈等有多大。将

在文本文件中更智能地读取'

基本上你需要一个Dictionary而不是一个数组或列表。您可以使用File.ReadLines方法读取所有行,然后根据空格和't(制表符)将它们分开,如下所示:

var values = File.ReadLines("path")
    .Select(line => line.Split(new [] { ' ', ''t' }, StringSplitOptions.RemoveEmptyEntries))
    .ToDictionary(parts => int.Parse(parts[1]), parts => parts[0]);

那么values[208]就会得到aabcdef。它看起来像一个数组,不是吗?)

还要确保没有重复的数字,因为Dictionary键应该是唯一的,否则你会得到一个异常

我一直在思考如何改进其他答案,我发现了基于Regex的替代解决方案,这使得搜索到整个字符串(无论是来自文件还是不是)更安全。

检查是否可以修改整个正则表达式以包含其他分隔符。示例表达式将检测空格和制表符。

在一天结束的时候,我发现MatchCollection返回一个更安全的结果,因为你总是知道第三组是一个整数,第二组是一个文本,因为正则表达式为你做了很多检查!

StringBuilder builder = new StringBuilder();
builder.AppendLine("djdodjodo't't3893983");
builder.AppendLine("dddfddffd't't233");
builder.AppendLine("djdodjodo't't39838");
builder.AppendLine("djdodjodo't't12");
builder.AppendLine("djdodjodo't't444");
builder.AppendLine("djdodjodo't't5683");
builder.Append("djdodjodo't't33");
// Replace this line with calling File.ReadAllText to read a file!
string text = builder.ToString();
MatchCollection matches = Regex.Matches(text, @"([^'s^'t]+)(?:['s't])+([0-9]+)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
// Here's the magic: we convert an IEnumerable<Match> into a dictionary!
// Check that using regexps, int.Parse should never fail because
// it matched numbers only!
IDictionary<int, string> lines = matches.Cast<Match>()
                                    .ToDictionary(match => int.Parse(match.Groups[2].Value), match => match.Groups[1].Value);
// Now you can access your lines as follows:
string value = lines[33]; // <-- By value

更新:

正如我们在聊天中讨论的那样,这个解决方案在您向我展示的一些实际用例中不起作用,但它不是不起作用的方法,而是您的特定用例,因为键是"某物"。[某事]"(例如:address.Name).

我已经将给定的正则表达式更改为(['w'.]+)['s't]+([0-9]+),因此它涵盖了键具有点的情况。

它是关于改进匹配正则表达式以满足您的要求!;)

更新2:

因为你告诉我你需要任何字符的键,所以我把正则表达式改为([^'s^'t]+)(?:['s't])+([0-9]+)

现在它的意思是键是除了空格和制表符以外的任何东西

更新3:

我也看到你卡在。net 3.0,而ToDictionary是在。net 3.5中引入的。如果你想在。net 3.0中获得相同的方法,将ToDictionary(...)替换为:

Dictionary<int, string> lines = new Dictionary<int, string>();
foreach(Match match in matches)
{
      lines.Add(int.Parse(match.Groups[2].Value), match.Groups[1].Value);
}