【问题标题】:Read just [Brackets] string from a text file [duplicate]从文本文件中仅读取 [Brackets] 字符串 [重复]
【发布时间】:2018-06-19 06:20:17
【问题描述】:

我有一个名为 hello.txt 的文本文件,其中包含以下文本:

[Hello] 这是堆栈溢出,我非常喜欢 [THIS]。我使用 [堆栈] 寻求帮助。

我只想要一个列表框中的[ ](括号字符串)。

我试过了:

using (StringReader reader = new StringReader(File Location))
{
    string line;

    while ((line = reader.ReadLine()) != null)
    {
        string input = line;
        string output = input.Split('[', ']')[1];
        MessageBox.Show(output);
    }
}

但这对我不起作用。

【问题讨论】:

标签: c# .net


【解决方案1】:

这就是你要找的东西

string a = "Someone is [here]";
string b = Regex.Match(a, @"\[.*?\]").Groups[0].Value;
Console.WriteLine(b);

//or if you need all occurences
foreach(Match match in Regex.Matches(a, @"\[.*?\]"))
{
    Console.WriteLine(match.Groups[0].Value);
}

【讨论】:

  • 这会起作用,但我的答案中的模式要快得多。速度几乎翻倍。对于小文本文件,差异可能不大,但对于大文本文件,您会注意到差异。
  • @RacilHilan 愿意解释为什么会这样?
  • 有什么要解释的?该模式更快,因为它做的工作更少(即找到匹配项的步骤更少)。在regex101.com 中试试看。对于问题中的字符串,您的模式需要 26 步,而我的模式需要 12 步。这还不到包含 3 个匹配项的一行的一半。
  • 另外你需要Groups[0],而不是Groups[1]。您从重复问题的已接受答案中删除了括号并忘记更改组。您也可以使用match.Value(不需要群组),甚至可以像我在回答中那样使用match
  • 所以@RacilHilan 对不起,但我不同意你的正则表达式会更快,因为我用模式和时间运行测试说不同的故事。
【解决方案2】:

您可以为此创建一个函数,它接受三个参数第一个输入字符串、起始字符串和结束字符串,并返回这两个字符串之间的值列表

private static IEnumerable<string> GetListOfString(string input, string start, string end)
{
   var regex = new Regex(Regex.Escape(start) + "(.*?)" + Regex.Escape(end));
   var matches = regex.Matches(input);
   return (from object match in matches select match.ToString()).ToList();
}

【讨论】:

    【解决方案3】:

    您可以使用如下正则表达式:

    var pattern = @"\[[^\]]*]";
    while ((line = reader.ReadLine()) != null) {
        var matches = Regex.Matches(line, pattern);
    
        foreach (var m in matches) {
            MessageBox.Show(m);
        }
    }
    

    此模式在方括号之间查找不是右方括号的任何内容。

    如果您想要括号之间的字符串而不需要括号本身,您可以从每个匹配项中修剪括号:

    MessageBox.Show(m.Value.Substring(1, m.Value.Length - 2));
    

    或者你可以使用这个模式:

    var pattern = @"\[([^\]]*)]";
    while ((line = reader.ReadLine()) != null) {
        var matches = Regex.Matches(line, pattern);
    
        foreach (Match m in matches) {
            MessageBox.Show(m.Groups[1]);
        }
    }
    

    【讨论】:

    • 为什么你总是在 while 循环中创建具有相同模式的新变量 patern?您可以在 while 循环之前创建它。
    • @RomanDoskoch 我最初只提供了while 中的代码,但后来为了清楚起见决定添加while。我把图案移到外面。感谢您的来信。
    【解决方案4】:

    这是使用 LINQ 的另一种方法

    string[] text = "[Hello] this is stack overflow and I Love [THIS] a lot. I use [Stack] for help.".Split(' ');
    var wantedString = text.Where(s => s.StartsWith("[") && s.EndsWith("]"));
       foreach(string word in wantedString)
          {
               Console.WriteLine(word);
          }
    

    【讨论】:

    • 在被空格分割时会失败,即... a [lot]. I ...
    • line 变量是字符串,而不是字符串数组。将其转换为字符串数组只是为了使用 LINQ 是没有意义的。
    • @RomanDoskoch 是的,确实如此。谢谢。
    • 这实际上是我首先想到的。我认为将字符串转换为数组没有问题,除了@Roman Doskoch 提到的。
    猜你喜欢
    • 2016-07-14
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-07-16
    • 2015-05-09
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    相关资源
    最近更新 更多