C# 如何在两个选项卡之间查找文本

C# 如何在两个选项卡之间查找文本,c#,parsing,text,C#,Parsing,Text,我有一个类似于以下内容的文件: 托马斯|诺德斯特罗姆|瑞典|欧洲|世界 (上行中的字符“|”表示选项卡,新列) 现在我想要一个只包含第4列中文本的字符串 我已经成功地在队列中的某个位置找到了字符。但这一点会随着每列中och字符的数量而变化。 我真的需要一些很好的意见 提前谢谢 /Tomas这可以使用如下Split方法完成: string s = "Tomas|Nordstrom|Sweden|Europe|World"; string[] stringArray = s.Split( new s

我有一个类似于以下内容的文件:

托马斯|诺德斯特罗姆|瑞典|欧洲|世界

(上行中的字符“|”表示选项卡,新列)

现在我想要一个只包含第4列中文本的字符串

我已经成功地在队列中的某个位置找到了字符。但这一点会随着每列中och字符的数量而变化。 我真的需要一些很好的意见

提前谢谢


/Tomas

这可以使用如下
Split
方法完成:

string s = "Tomas|Nordstrom|Sweden|Europe|World";
string[] stringArray = s.Split( new string[] { "|" }, StringSplitOptions.None );

Console.WriteLine( stringArray[3] );
string[] stringRegex = Regex.Split( s, @"\|+" );
这将打印出“Europe”,因为它位于stringArray的索引3处

编辑:

使用Regex可以实现同样的效果,如下所示:

string s = "Tomas|Nordstrom|Sweden|Europe|World";
string[] stringArray = s.Split( new string[] { "|" }, StringSplitOptions.None );

Console.WriteLine( stringArray[3] );
string[] stringRegex = Regex.Split( s, @"\|+" );

基本算法是迭代字符,直到找到n-1个制表符,然后将字符带到下一个制表符或字符串的末尾

根据需求,如果性能至关重要,您可能需要手动实现扫描算法

您可能会惊讶于字符串拆分的速度有多慢。好吧,这不是它本身,但总体方法需要:

  • 扫描到字符串的末尾
  • 在堆上创建所有拆分部分
  • 垃圾收集
考虑以下两种方法的基准:

void Main()
{
    string source = "Tomas\tNordstrom\tSweden\tEurope\tWorld";

    var sw = Stopwatch.StartNew();

    string result = null;

    var n = 100000000;

    for (var i = 0; i < n; i++)
    {
        result = FindBySplitting(source);
    }

    sw.Stop();

    var splittingNsop = (double)sw.ElapsedMilliseconds / n * 1000000.0;
    Console.WriteLine("Splitting. {0} ns/op",splittingNsop);

    Console.WriteLine(result);

    sw.Restart();

    for (var i = 0; i < n; i++)
    {
        result = FindByScanning(source);
    }

    sw.Stop();

    var scanningNsop = (double)sw.ElapsedMilliseconds / n * 1000000.0;
    Console.WriteLine("Scanning. {0} ns/op",
        scanningNsop);

    Console.WriteLine(result);

    Console.WriteLine("Scanning over splitting: {0}", splittingNsop / scanningNsop);
}

string FindBySplitting(string s)
{
    return s.Split('\t')[3];
}

string FindByScanning(string s)
{
    int l = s.Length, p = 0, q = 0, c = 0;
    while (c++ < 4 - 1)
        while (p < l && s[p++] != '\t')
            ;
    for (q = p; q < l && s[q] != '\t'; q++)
        ;
    return s.Substring(p, q - p);
}

查找
String.Split
.Split by
\t
并转到索引3如果它们保证是单个单词,您可以用“\w+”读取正则表达式。这是一个很好的答案,我无法忍受使用单字母变量名,除非它们仅在for循环或lambda表达式之类的非常狭窄的范围内使用。请考虑编辑您的代码,为变量提供有意义的名称。而且不仅仅是单个字母。
count
用于什么?你必须阅读并理解代码才能知道。如果您要调用它
delimiterCount
,您就不必阅读整个代码来理解它。@ZoharPeled不同意变量名。但编辑了代码以使其更加一致。我建议你检查一下,你不必同意我的意见;这只是我的意见。然而,它是基于经验(我和其他人)-代码可读性越强,维护起来就越容易。为了好玩,一年后再来看看这篇文章,看看你花了多少时间和精力来理解你在这里写的东西。我保证如果你使用有意义的名字会更容易。顺便说一句,除非在一个紧密的循环中完成这种类型的事情,否则split和代码之间的性能差异是完全可以忽略的——而且根本不值得首先编写
findbyscan
方法。