【问题标题】:Extract matching text using regular expression使用正则表达式提取匹配文本
【发布时间】:2012-10-11 05:16:18
【问题描述】:

我必须从报纸文章中提取摘要。摘要是根据给定的关键字和下面提到的规则提取的。

  1. 摘要应为 200 个字符。

  2. 只要有关键字就从文章中的那句话开始打印 出现在该句子中并打印最多 200 个字符

  3. 如果匹配的句子出现在文章的结尾,使得 总结出来少于200个字符,然后移动 从匹配句子回到前面的句子直到 最后打印包含匹配句子的 200 个字符 最后。

到目前为止我所做的是......

var regex = new Regex(keyword+@"(.{0,200})");

foreach (Match match in regex.Matches(input))
{
    var result = match.Groups[1].Value;
    Console.WriteLine(result);

    // work with the result
}

上述代码成功到达第一个匹配句子,但开始打印AFTER关键字最多200个字符,而不是匹配句子的开头。

如果在打印 200 个字符之前到达文章结尾,则不会回溯。

请指导我应该如何进行。即使有人不知道完整的解决方案,请在问题的子部分帮助我。

【问题讨论】:

    标签: c# regex


    【解决方案1】:
    var nextIndex = input.IndexOf(keyword);
    
    while (nextIndex != -1)
    {
        var index = nextIndex;
        // To start the 200chars result from right after the keyword, do instead:
        // var index = nextIndex + keyword.Length;
    
        // If you want to stop after you reached the end of the text once:
        // var end = false;
    
        if (index + 200 >= input.Length)
        {
            index = input.Length - 200;
    
            // If you want to stop after you reached the end of the text once:
            // var end = true;
        }
    
        var result = index < 0 ? input : input.Substring(index, 200);
    
        Console.WriteLine(result);
    
        // If you want to stop after you reached the end of the text once:
        // if (end) { break; }
    
        nextIndex = input.IndexOf(keyword, nextIndex + 1);
    }
    

    如果您希望搜索不区分大小写,只需在两个IndexOfs 中添加StringComparison.OrdinalIgnoreCase 作为另一个参数。

    【讨论】:

    • 关键字是英文单词,不是正则表达式
    • @mhasan 相应地更改了解决方案。
    【解决方案2】:

    改用这个,

    var regex = new Regex( @"(" + keyword+ @".{0,200})");
    

    这将确保关键字也包含在内。否则你也可以使用这个

    var result = match.Value;
    

    您还指定了 {0,200},因此它将匹配大小在 0 到 200 之间的任何实例,因此它将匹配任意数量的字符,直到到达文章末尾。让我确切地知道你想在这方面实现什么。

    如果您希望表达式从句子的开头返回结果,请尝试这样做

    var regex = new Regex( @"\.(.+?" + keyword+ @".*)");
    

    但在这种情况下,您将不得不手动删除多余的字符,因为此正则表达式往往会获取比您预期更多的字符。它将从包含关键字的句子的开头获取字符,直到段落的结尾。

    【讨论】:

      【解决方案3】:

      是否需要使用正则表达式?如果不是,这是一个粗略的选择:

      var index = input.IndexOf(keyword) + keyword.Length;
      var remaining = input.Length - index;
      index = remaining >= 200 ? index : index -= 200 - remaining;
      
      Console.WriteLine(input.Substring(index, 200));
      

      【讨论】:

      • 你有很好的答案,扎克。您只是忘记检查结果索引是否为负数。欢迎来到 SO!
      • 感谢您帮助我解决 Yorye 和 Zac..上面的代码成功到达第一个匹配的句子,但从关键字开始打印最多 200 个字符而不是匹配句子的开头。
      • @mhasan 你想让它从关键字后面的 200 开始吗​​?
      • 把第一行改成这个就行了。正如 Yorye 指出的那样,也许您应该在使用 index 之前检查它是否为负数。我假设您的输入将始终包含您正在寻找的句子。 var index = input.IndexOf(keyword) + keyword.Length;
      • @Zac 我说的其实是找到了关键字in但整个文本小于200chars的情况,所以在第3行之后,索引将为负数。
      猜你喜欢
      • 2011-01-12
      • 1970-01-01
      • 2021-06-11
      • 2011-09-27
      • 2011-09-18
      • 2015-03-08
      • 1970-01-01
      相关资源
      最近更新 更多