Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:解析文本文件_C#_Regex_Text Files - Fatal编程技术网

C#:解析文本文件

C#:解析文本文件,c#,regex,text-files,C#,Regex,Text Files,我有一个文本文件,文件的内容如下: idiom: meaning description. o example1. o example2. idiom: meaning description. o example1. o example2. . . . 正如您所看到的,该文件包含上述段落,每个段落都有一些我想要提取的数据(请注意,示例以o开头)。例如,我们有以下数据: public class Idiom { public string Idiom { get; set; }

我有一个文本文件,文件的内容如下:

idiom: meaning
description.
o example1.
o example2.

idiom: meaning
description.
o example1.
o example2.

.
.
.
正如您所看到的,该文件包含上述段落,每个段落都有一些我想要提取的数据(请注意,示例以
o
开头)。例如,我们有以下数据:

public class Idiom
{
    public string Idiom { get; set; }
    public string Meaning { get; set; }
    public string Description { get; set; }
    public IList<IdiomExample> IdiomExamples { get; set; }
}

public class IdiomExample
{
    public string Item { get; set; }
}

提前感谢

类似的东西(没有测试,只是一个建议)


这样的办法应该行得通。我还没有测试过它,但是经过一点调试,我想它会工作的

我知道您将
regex
放在标记中,但这也是提取行的一种方法

using ( var textReader = new StreamReader("idioms.txt") )
{
    var idioms = new List<Idiom>();
    string line;
    while ( ( line = textReader.ReadLine() ) != null )
    {
        var idiom = new Idiom();
        if ( line.StartsWith("idiom: ") )
        {
            idiom.Meaning = line.Replace("idiom: ", string.Empty);
            idiom.Description = textReader.ReadLine();

            while ( ( line = textReader.ReadLine() ) != null )
            {
                if ( line.StartsWith("o ") )
                    idiom.IdiomExamples.Add(new IdiomExample { Item = line.Replace("o ", string.Empty) });
                else break;
            }
            idioms.Add(idiom);
        }
    }

    ///idioms ready
}
使用(var textReader=newstreamreader(“idioms.txt”))
{
var-idioms=newlist();
弦线;
而((line=textReader.ReadLine())!=null)
{
var-idiom=新习惯用法();
if(line.StartsWith(“成语:”)
{
成语.means=line.Replace(“成语:”,string.Empty);
idiom.Description=textReader.ReadLine();
而((line=textReader.ReadLine())!=null)
{
if(带“o”的行开始)
Add(new-IdiomExample{Item=line.Replace(“o”,string.Empty)});
否则就断了;
}
成语。添加(成语);
}
}
///成语准备好了吗
}

这是解决您问题的我的正则表达式:

(?<section>(?<idiom>^.+?):(?<meaning>.+)[\n](?<description>.*?)(?<examples>(?<example>o.+[\s\r\n])+))
嗯,你有3种方法来处理你的文件。首先是使用regex,它是开发速度最快、性能解决方案最慢的。第二种方法是将文本解析为字符串,并使用LINQ或任何您想要的方法。对我来说,这种方法有缺陷、不可扩展等等,但它有更好的性能,如果处理非常大的文件,这一点非常关键。第三种是使用形式语法和终端机器或类似的东西。。。我从来没有实现过这样的东西,但我知道,它的开发和维护速度很快,而且非常困难,所以我建议您使用regexp,然后迁移到另一种方法,如果性能将成为您的瓶颈


希望这有帮助

您的示例没有说明,但此regexp接受可选说明。它让您了解如何解析输入,而不是整个C代码

请看这里并查看分组

(?smx)
^ 
([^:\n]+):\s*([^\n]+)
\n([^o].*?\n|)
(^o.*?)
(?=\Z|^[^o:\n]+:)
在此之后:

  • 第一组有成语

  • 第2组有意义

  • 第3组有说明(如有)

  • 第4组有所有的例子


  • 此正则表达式不会将示例解析为多个示例,这是下一项工作。另外,你可能不喜欢一些新词。

    是的,有很多方法。你试过什么吗?事实上没有,我对找到正则表达式的模式有点困惑。它的意思总是一行吗?使用有限状态机:有4种状态:1:空行/文件开始(需要习惯用法);第二个-习语,3d-描述,第四个-示例;转换为:1->1;1 -> 2; 2 -> 3; 3 -> 4; 4 -> 4; 4->1.我的文本文件中没有
    成语
    ,只是举个例子。它可能是任何东西。你希望我们猜到吗?从你的声誉判断,你应该知道如何提问。请编辑您的问题以显示相关输入。非常感谢,但似乎它只适用于一段@锡瓦纳菲菲把它改成了多副伞。在你的C#中试试,不是在regex101中工作,而是在我的工具中工作,regex101有时会有bug
    (?<section>(?<idiom>^.+?):(?<meaning>.+)[\n](?<description>.*?)(?<examples>(?<example>o.+[\s\r\n])+))
    
    RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace | RegexOptions.CultureInvariant
    
    (?smx)
    ^ 
    ([^:\n]+):\s*([^\n]+)
    \n([^o].*?\n|)
    (^o.*?)
    (?=\Z|^[^o:\n]+:)