C#:对于TextReader的每个ReadLine(),用一个分隔符解析字符串的有效方法是什么?
我的目标是将ListView的代理列表加载到从.txt文件读取的两列(代理|端口)中。我如何继续使用分隔符“:”将每个readline()拆分为代理和端口变量?
这是我到目前为止所做的,
public void loadProxies(string FilePath)
{
string Proxy; // example/temporary place holders
int Port; // updated at each readline() loop.
using (TextReader textReader = new StreamReader(FilePath))
{
string Line;
while ((Line = textReader.ReadLine()) != null)
{
// How would I go about directing which string to return whether
// what's to the left of the delimiter : or to the right?
//Proxy = Line.Split(':');
//Port = Line.Split(':');
// listview stuff done here (this part I'm familiar with already)
}
}
}
如果没有,有更有效的方法吗?
答案 0 :(得分:2)
你可以这样分开它们:
string line;
string[] tokens;
while ((Line = textReader.ReadLine()) != null)
{
tokens = line.Split(':');
proxy = tokens[0];
port = tokens[1];
// listview stuff done here (this part I'm familiar with already)
}
最好在C#中为变量使用小写字母名称,因为其他名称是为类/命名空间名称等保留的。
答案 1 :(得分:2)
string [] parts = line.Split(':');
string proxy = parts[0];
string port = parts[1];
答案 2 :(得分:2)
如何在整个文件上运行正则表达式?
var parts=
Regex.Matches(input, @"(?<left>[^:]*):(?<right>.*)",RegexOptions.Multiline)
.Cast<Match>()
.Where(m=>m.Success)
.Select(m => new
{
left = m.Groups["left"],
right = m.Groups["right"]
});
foreach(var part in parts)
{
//part.left
//part.right
}
或者,如果它太大,为什么不用屈服方法Linqify ReadLine操作?
static IEnumerable<string> Lines(string filename)
{
using (var sr = new StreamReader(filename))
{
while (!sr.EndOfStream)
{
yield return sr.ReadLine();
}
}
}
然后像这样运行:
var parts=Lines(filename)
.Select(
line=>Regex.Match(input, @"(?<left>[^:]*):(?<right>.*)")
)
.Where(m=>m.Success)
.Select(m => new
{
left = m.Groups["left"],
right = m.Groups["right"]
});
foreach(var part in parts)
{
//part.left
//part.right
}
答案 3 :(得分:1)
就效率而言我希望你很难被击败:
int index = line.IndexOf(':');
if (index < 0) throw new InvalidOperationException();
Proxy = line.Substring(0, index);
Port = int.Parse(line.Substring(index + 1));
这避免了与Split
关联的数组构造/分配,并且只能看到第一个分隔的数组。但我应该强调,除非数据量巨大,否则这不太可能是真正的性能瓶颈,所以任何方法都应该没问题。事实上,也许最重要的事情(我已被下面的评论提醒)是在添加时暂停用户界面:
myListView.BeginUpdate();
try {
// TODO: add all the items here
} finally {
myListView.EndUpdate();
}
答案 4 :(得分:0)
您可能想尝试这样的事情。
var items = File.ReadAllText(FilePath)
.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
.Select(line => line.Split(':'))
.Select(pieces => new {
Proxy = pieces[0],
Port = int.Parse(pieces[1])
});
如果您知道文件末尾没有杂散换行符,则可以执行此操作。
var items = File.ReadAllLines(FilePath)
.Select(line => line.Split(':'))
.Select(pieces => new {
Proxy = pieces[0],
Port = Convert.ToInt32(pieces[1])
});