C#:通过TextReader的ReadLine()解析带有一个分隔符的字符串的有效方法是什么?

时间:2010-03-04 23:53:56

标签: c# listview split

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)
            }
        }
    }

如果没有,有更有效的方法吗?

5 个答案:

答案 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]) 
    });
相关问题