C#如何从字符串中提取单词并将它们放入类成员中

时间:2017-05-05 10:27:17

标签: c# .net string

我对c#字符串操作有疑问,感谢您的帮助。 我有一个包含许多行的文件。它看起来像这样:

firstWord   number(secondWord)    thirdWord(Phrase)  Date1  Date2
firstWord number(secondWord)         thirdWord(Phrase)   Date1     Time1
...

我需要将这些单词分开并将它们放在类属性中。正如您所看到的那样,问题是单词之间的空格不一样,有时候它们之间有一个空格,有时会有八个空格。第二个问题是,在第三个位置出现一个包含2到5个单词的短语(再次用空格划分或有时用_或 - 表示),它需要被视为一个字符串 - 它必须是一个类成员。该课程应如下所示:

class A
string a = firstWord;
int b = number;
string c = phrase;
Date d = Date1;
Time e = Time1;

如果您有任何想法如何解决这个问题,我会感激不尽。谢谢。

4 个答案:

答案 0 :(得分:1)

使用以下步骤:

  1. 使用File.ReadAllLines()获取string[],其中每个元素代表文件的一行。
  2. 对于每一行,请使用string.Split()并将您的行划分为单个单词。使用空格和括号作为分隔符。这将为您提供一系列单词。称之为arr
  3. 现在创建一个类的对象并像这样分配:

    string a = arr[0];
    int b = int.Parse(arr[1]);
    string c = string.Join(" ", arr.Skip(4).Take(arr.Length - 6));
    Date d = DateTime.Parse(arr[arr.Length - 2]);
    Date e = DateTime.Parse(arr[arr.Length - 1]);
    
  4. 唯一棘手的问题是string c以上。这里的逻辑是元素号。 4到最后的第3个元素,所有这些元素构成了短语部分,因此我们使用linq提取这些元素并将它们连接在一起以获取您的短语。这显然要求短语本身不包含任何括号,但通常不应该是我假设的情况。

答案 1 :(得分:0)

您需要一个循环string - 和TryParse - 方法:

var list = new List<ClassName>();
foreach (string line in File.ReadLines(path).Where(l => !string.IsNullOrEmpty(l)))
{
    string[] fields = line.Trim().Split(new char[] { }, StringSplitOptions.RemoveEmptyEntries);
    if (fields.Length < 5) continue;

    var obj = new ClassName();
    list.Add(obj);

    obj.FirstWord = fields[0];

    int number;
    int index = fields[1].IndexOf('(');
    if (index > 0 && int.TryParse(fields[1].Remove(index), out number))
        obj.Number = number;

    int phraseStartIndex = fields[2].IndexOf('(');
    int phraseEndIndex = fields[2].LastIndexOf(')');
    if (phraseStartIndex != phraseEndIndex)
    {
        obj.Phrase = fields[2].Substring(++phraseStartIndex, phraseEndIndex - phraseStartIndex);
    }

    DateTime dt1;
    if(DateTime.TryParse(fields[3], out dt1))
        obj.Date1 = dt1;

    DateTime dt2;
    if (DateTime.TryParse(fields[3], out dt2))
        obj.Date2 = dt2;
}

答案 2 :(得分:0)

以下正则表达似乎涵盖了我想象你需要的东西 - 至少是一个好的开始。

^(?<firstWord>[\w\s]*)\s+(?<secondWord>\d+)\s+(?<thirdWord>[\w\s_-]+)\s+(?<date>\d{4}-\d{2}-\d{2})\s+(?<time>\d{2}:\d{2}:\d{2})$

这会捕获5个命名组

  • firstWord是任何字母数字或空格
  • secondWord是任何数字条目
  • thirdWord任何字母数字,空格下划线或连字符
  • date是任何iso格式的日期(未验证日期)
  • time任何时间(未经过验证的时间)

任何数量的空格都用作分隔符 - 但您必须Trim()任何组捕获。它对你的格式做了很多假设的地狱(日期是ISO格式的,时间是hh:mm:ss)。

您可以像这样使用它:

Regex regex = new Regex( @"(?<firstWord>[\w\s]*)\s+(?<secondWord>\d+)\s+(?<thirdWord>[\w\s_-]+)\s+(?<date>\d{4}-\d{2}-\d{2})\s+(?<time>\d{2}:\d{2}:\d{2})$", RegexOptions.IgnoreCase );
var match = regex.Match("this is the first word        123     hello_world    2017-01-01 10:00:00");
if(match.Success){
    Console.WriteLine("{0}\r\n{1}\r\n{2}\r\n{3}\r\n{4}",match.Groups["firstWord"].Value.Trim(),match.Groups["secondWord"].Value,match.Groups["thirdWord"].Value,match.Groups["date"].Value,match.Groups["time"].Value);
}

http://rextester.com/LGM52187

答案 3 :(得分:-1)

你必须使用正则表达式,你可以看一下here作为起点。所以例如要获得第一个单词,你可以使用这个

create.js.erb