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]+:)
在此之后:
此正则表达式不会将示例解析为多个示例,这是下一项工作。另外,你可能不喜欢一些新词。是的,有很多方法。你试过什么吗?事实上没有,我对找到正则表达式的模式有点困惑。它的意思总是一行吗?使用有限状态机:有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]+:)