【问题标题】:How can read a file, split the strings in it, and write the output to a hashtable in C#?如何在 C# 中读取文件、拆分其中的字符串并将输出写入哈希表?
【发布时间】:2009-12-06 19:43:38
【问题描述】:

我需要在 C# 中读取文件并将字符串拆分为哈希表。

例如;

1231231 你好这是第一个条目/你好这是第二个条目

目前,我正在使用StreamReader 逐行读取文件中的行,然后将每一行拆分为 3 个不同的字符串。例如,“1231231”对一个字符串,然后“/”符号到另一个字符串,最后在“/”符号到另一个字符串之后。

1231231 将是哈希表的键,其他将是哈希表的值。我被困在这部分。

【问题讨论】:

  • 听起来好像有人不再做作业了。
  • 所以key始终是行首的数字,你想要一个以/分隔的字符串列表作为值吗?
  • 我认为你需要澄清你想要做什么。如前所述,您似乎希望在哈希表中有两个条目,一个带有 key = 1231231,value = "Hi this is the first entry",第二个带有 key = 1231231,value = "hi this is the second entry" .这是不可能的。
  • 放大 Jason 的评论:哈希表中的键必须是唯一的。
  • 如果我没看错的话,听起来您实际上是在尝试使用一个键并针对它存储两个项目。哈希表的每个键只有一个值,因此“您好,这是第一个条目/您好,这是第二个条目”将是值,或者您需要两个键,或者您需要为这两个值存储不同的数据结构(一个具有 2 个字符串值的类,例如 - 一个元组,它将在 .NET 4 中出现)。

标签: c# file split hashtable


【解决方案1】:

假设您有相当常规的输入集,您可能希望为此使用 regular expression

这个模式看起来像你想要的:

^(\d+)\s+([^/]+)\s+/\s+(.+)$

那就是:

  • ^ : 定位到字符串的开头
  • (\d+) :一位或多位数字
  • \s+ : 1 个或多个空白字符
  • ([^/]+) : 1 个或多个不等于 '/' 的字符
  • \s+/\s+ : 1 个或多个空格字符加上 1 个斜线和 1 个或多个空格字符
  • (.+) : 1 个或多个任意字符
  • $ : 锚到字符串结尾

【讨论】:

  • Regex 是一只美丽的野兽 :) 使用它直到性能成为问题,然后重写。
【解决方案2】:

使用 Bobby 的正则表达式..

    static void Main(string[] args)
    {
            Hashtable hashtable = new Hashtable();
            string[] fileLines = File.ReadAllLines(@"PATH\FILE.TXT");

            foreach (string line in fileLines)
            {
            var match =  Regex.Match(line, @"^(\d+)\s+([^/]+)\s+/\s+(.+)$");
            hashtable.Add(match.Groups[0].ToString(), new string[] { match.Groups[1].ToString(), match.Groups[2].ToString() });
            }
        }

哈希表值作为字符串数组插入,因为键必须是唯一的。

【讨论】:

    【解决方案3】:

    可能更理想,但它会起作用:

            char stringSplit = '/';
            char keySplit = ' ';
            Dictionary<string,string[]> dictionary = new Dictionary<string, string[]>(1000);
            using(StreamReader sr = new StreamReader(@"c:\somefile.txt"))
            {
                string line;
                while ((line = sr.ReadLine()) != null)
                {
                    int keyIndex = line.IndexOf(keySplit);
                    string key = line.Substring(0, keyIndex);
                    string[] values = line.Substring(keyIndex + 1).Split(stringSplit);
                    dictionary.Add(key,values);
                }
            }
    

    【讨论】:

      【解决方案4】:

      将条目添加到哈希表的代码:

      Hashtable hashtable = new Hashtable(new EqualityComparer());
      string[] fileLines = File.ReadAllLines(@"somePath");
      foreach (var fileLine in fileLines)
      {
          int indexOfSpace = fileLine.IndexOf(' ');
          int indexOfSlash = fileLine.IndexOf('/');
          string keyString = fileLine.Remove(indexOfSpace);
          string firstValue = 
                   fileLine.Substring(indexOfSpace, indexOfSlash - indexOfSpace - 1);
          string secondValue = fileLine.Substring(indexOfSlash + 1);
          hashtable.Add(new Key(keyString), firstValue);
          hashtable.Add(new Key(keyString), secondValue);
      }
      

      封装相同字符串的键类:

      public class Key
      {
          private readonly string s;
      
          public Key(string s)
          {
              this.s = s;
          }
      
          public string KeyString
          {
              get { return s; }
          }
      }
      

      提供 GetHashCode 功能的相等比较器,以使基于相同字符串的两个键转到哈希表中的相同条目:

      public class EqualityComparer : IEqualityComparer
      {
          public bool Equals(object x, object y)
          {
              return ReferenceEquals(x, y);
          }
      
          public int GetHashCode(object obj)
          {
              return ((Key) obj).KeyString.GetHashCode();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-05-23
        • 1970-01-01
        • 1970-01-01
        • 2019-09-24
        • 2020-05-23
        • 2020-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多