我有一个文本文件,其中包含我要提取的分隔符之间的一些数字,并将它们添加到两个不同的列表中。我要填充的列表是:
points = new List<string>();
coords = new List<string>();
这是输入文件的样子:
blah
blah
point [
0 50 50,
50 50 50,
50 0 50,
0 0 50,
]
blah
blah
coordIndex [
3,2,0,-1,
2,1,0,-1,
]
blah
blah
blah
blah
point [
0 50 0,
50 50 0,
50 0 0,
0 0 0,
]
blah
blah
coordIndex [
3,0,2,-1,
0,1,2,-1,
]
blah
blah
我想要做的是按照以下逻辑获取数字(包括逗号):
获取关键字“point [”和下一个“]”之间的界限。每一行都是一个“字符串”。
将这些行添加到列表“points”
获取关键字“coordIndex [”和下一个“]”之间的界限。每一行都是一个“字符串”。
将这些行添加到“coords”列表
到目前为止,我只是设法摆脱空白区域以“获取”点数字段,但我不知道如何填充列表。
有人可以帮忙吗?我很乐意使用正则表达式或其他任何选项。
代码
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
namespace parsing
{
class Program
{
static void Main(string[] args)
{
string inputFile = "Q:/inputFile.txt";
//Lists to be populated
var points = new List<string>();
var coords = new List<string>();
//Parsing the file
using (StreamReader readInputFile = new StreamReader(inputFile))
{
string line;
while ((line = readInputFile.ReadLine()) != null)
{
if (!string.IsNullOrWhiteSpace(line))
{
//Remove tabs
string line_noTabs = line.Replace("\t", "");
//Get lines between the keywords "point [" and the next "]". Each line is a "string".
//Add these lines to a the list "points"
//Get lines between the keywords "coordIndex [" and the next "]". Each line is a "string".
//Add these lines to a the list "coords"
}
}
}
}//end main
}//end program
}//end namespace
答案 0 :(得分:1)
您只需要遍历文件,一次一行并设置一系列标记,然后您可以稍后检查以查看文件的哪个块。
然后,您将检查标记以查看添加项目所需的列表。
您的代码需要看起来像这样:
using (StreamReader readInputFile = new StreamReader(inputFile))
{
string line;
bool isPoint = false;
bool isCoord = false;
Regex pointRegex = new Regex("point\\s+\\[");
Regex coordRegex = new Regex("coordIndex\\s+\\[");
Regex endBrace = new Regex("\\s*\\]\\s*");
while ((line = readInputFile.ReadLine()) != null)
{
if (!string.IsNullOrWhiteSpace(line))
{
//Remove tabs
string line_noTabs = line.Replace("\t", "");
if(pointRegex.IsMatch(line_noTabs))
{
isPoint = true;
continue;
}
else if(coordRegex.IsMatch(line_noTabs))
{
isCoord = true;
continue;
}
else if (endBrace.IsMatch(line_noTabs))
{
isPoint = false; //Reset
isCoord = false; //Reset
continue;
}
if(isPoint)
points.Add(line_noTabs);
else if(isCoord)
coords.Add(line_noTabs);
}
}
}
答案 1 :(得分:0)
这是一种方法:
\[([^\]]+)]
获取括号(https://regex101.com/r/sG4zO1/1)之间的所有内容。regexResult.Split(new char[0], StringSplitOptions.RemoveEmptyEntries)
在括号内获取一组数字。index % 2 == 0
,那么您正在查看point
值index % 2 == 1
,那么您有coordIndex
个值答案 2 :(得分:0)
如果您希望将每个 point \ coordIndex 批次中的每一行作为Item
中的新List
批处理,那么请使用(\d+\s\d+\s\d+)|(\d,\d,\d,-?\d,)
这样的正则表达式你会得到两组匹配 - 一组用于积分,一组用于coordIndexes(这取决于你给出的例子,如果数据可以变化,则必须改进正则表达式。)
如果稍后您需要使用 point \ coordIndex 字符串中的数字,则需要应用一些c#来“解析”字符串。
答案 3 :(得分:0)
试试这个。我将您的列表更改为整数。我起诉了Regex,但可以轻松地将代码更改为类似于代码的方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"C:\temp\test.txt";
static void Main(string[] args)
{
string input = File.ReadAllText(FILENAME);
string pattern = @"(?'type'\w+)\s+\[(?'array'[^\]]+)\]";
Regex expr = new Regex(pattern, RegexOptions.Singleline);
MatchCollection matches = expr.Matches(input);
//Lists to be populated
List<List<int>> points = new List<List<int>>();
List<List<int>> coords = new List<List<int>>();
foreach (Match match in matches)
{
string type = match.Groups["type"].Value;
string strArray = match.Groups["array"].Value;
StringReader reader = new StringReader(strArray);
string line = "";
while ((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
List<int> intArray = line.Split(new char[] { ',', ' '}, StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
switch (type)
{
case "point":
points.Add(intArray);
break;
case "coordIndex":
coords.Add(intArray);
break;
}
}
}
}
}
}
}