我有一个.txt文件,其中有大约500个条目,每个条目用新行分隔。文件大小约为13MB,每行的格式如下:
SomeText<tab>Value<tab>AnotherValue<tab>
我的问题是从程序的输入中找到某个“字符串”,从文件的第一列开始,并从两列中获取相应的Value
和AnotherValue
。
第一列未排序,但文件中的second
和third
列值实际上已排序。但是,这种排序对我来说没什么用处。
该文件是静态的,不会更改。我想在这里使用Regex.IsMatch()
,但我不确定这是否是最好的方法,一行一行。
如果查找时间会急剧增加,我可能会重新排列第一列(因此会对second
&amp; third
列进行排序。如果需要,有关如何实施此方法或上述方法的任何建议吗?
找到字符串后,我应该如何获取这两个列值?
修改 我意识到文件中会有相当多的搜索对用户的至少oe请求。如果我要找到一个值数组,如何返回某种具有相应匹配值的字典?
答案 0 :(得分:1)
也许使用此代码:
var myLine = File.ReadAllLines()
.Select(line => line.Split(new [] {' ', '\t'}, SplitStringOptions.RemoveEmptyEntries)
.Single(s => s[0] == "string to find");
myLine
是一个表示行的字符串数组。您还可以使用.AsParallel()
扩展方法来获得更好的性能。
答案 1 :(得分:0)
var firstFoundLine = File.ReadLines("filename").FirstOrDefault(s => s.StartsWith("string"));
if (firstFoundLine != "")
{
char yourColumnDelimiter = '\t';
var columnValues = firstFoundLine.Split(new []{yourColumnDelimiter});
var secondColumn = columnValues[1];
var thirdColumns = columnValues[2];
}
File.ReadLines
优于File.RealAllLines
因为您不需要读取整个文件 - 只有在找到匹配的字符串http://msdn.microsoft.com/en-us/library/dd383503.aspx
答案 2 :(得分:0)
将这种怪物解析为某种数据库 SQL Server / MySQL是首选,但如果由于各种原因无法使用它们,SQLite甚至Access或Excel都可以使用。 这样做一次并不难 完成后,搜索将变得简单快捷。
答案 3 :(得分:0)
GetLines(inputPath).FirstOrDefault(p=>p.Split(",")[0]=="SearchText")
private static IEnumerable<string> GetLines(string inputFile)
{
string filePath = Path.Combine(Directory.GetCurrentDirectory(),inputFile);
return File.ReadLines(filePath);
}
答案 4 :(得分:0)
您需要多少次进行此搜索? 如果您节省每次搜索的时间,那么启动时的某些预处理成本是否值得? 是否可以在启动时将所有数据加载到内存中? 将文件解析为对象并将结果粘贴到哈希表中?
我认为Regex不会比任何标准字符串选项更有帮助。你正在寻找一个固定的字符串值,而不是一个模式,但我仍然需要纠正。
<强>更新强> 假设“SomeText”是唯一的,您可以使用像这样的字典
数据表示来自文件的值。 MyData 是一个将它们保存在内存中的类。
public IEnumerable<string> Data = new List<string>() {
"Text1\tValue1\tAnotherValue1\t",
"Text2\tValue2\tAnotherValue2\t",
"Text3\tValue3\tAnotherValue3\t",
"Text4\tValue4\tAnotherValue4\t",
"Text5\tValue5\tAnotherValue5\t",
"Text6\tValue6\tAnotherValue6\t",
"Text7\tValue7\tAnotherValue7\t",
"Text8\tValue8\tAnotherValue8\t"
};
public class MyData {
public String SomeText { get; set; }
public String Value { get; set; }
public String AnotherValue { get; set; }
}
[TestMethod]
public void ParseAndFind() {
var dictionary = Data.Select(line =>
{
var pieces = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
return new MyData {
SomeText = pieces[0],
Value = pieces[1],
AnotherValue = pieces[2],
};
}).ToDictionary<MyData, string>(dat =>dat.SomeText);
Assert.AreEqual("AnotherValue3", dictionary["Text3"].AnotherValue);
Assert.AreEqual("Value7", dictionary["Text7"].Value);
}
hth,
艾伦