【问题标题】:How do I find all occurrences of a specific sentence within a string?如何在字符串中找到所有出现的特定句子?
【发布时间】:2012-08-26 13:59:15
【问题描述】:

假设我有一个这样的字符串:

string source = "Today is friday! I'm am having trouble programming this. Today is friday! Tomorrow is saturday. Today is friday!"

我想搜索这个字符串,抓住所有说“今天是星期五!”的句子,然后用我刚刚找到的句子创建一个新字符串。

上述字符串的预期结果是:

string output = "Today is friday!Today is friday!Today is friday!"

编辑:LINQ 不是强制性的。

谢谢!

【问题讨论】:

  • 你试过什么?为什么您认为 LINQ 是解决您的任务的正确选择?
  • 不确定你想要什么。如果你想每次检查一个句子,也许只计算它的出现次数会更容易?
  • 遇到I like programming and today is friday.这样的句子你想要什么。你想捕捉整个句子还是只捕捉today is friday 部分?
  • 什么想法?这是一个a OR b 问题,您需要指定是否需要结果ab。照原样,它有点模棱两可。另外,您是否在解析诸如作业之类的字符串,其中的字符串可能很少有标点符号或普通文本,而这些字符串可能有ellipsis 和问号分隔您的句子?
  • 我想捕捉整个句子。我正在解析一个可以包含任何类型输入的字符串块。 (我正在解析的字符串)可以来自很多地方,因此我无法预测它将包含什么。

标签: c# regex linq substring


【解决方案1】:

好的,你需要做的第一件事就是把你的一个字符串变成多个字符串。 String.Split() 应该在这里工作,不需要正则表达式:

var sentences = inputString.Split('.','!');

获得单个句子后,您只需寻找符合条件的句子:

var todayIsFridaySentences = sentences.Where(s=>s.Contains("Today is friday"));

...然后最后将它们重新组合在一起;如果您绝对必须为此使用 Linq:

var ouputString = todayIsFridaySentences
                     .Aggregate(new StringBuilder(), (s,b) => b.Append(s))
                     .ToString();

【讨论】:

  • 这不处理 '.' 的情况要么 '!'没有结束一个句子。 “先生”呢?要么 '!'用于表示“阶乘”。
  • 示例中都不存在这些情况,并且 OP 没有说它们是问题。没有人说过这个解决方案在一般情况下有效。如果必须,那么解决方案将变得非常困难;句子必须用两个空格隔开(这个标准越来越少见),否则这些边缘情况中的一个或多个将被忽略或导致合法的断句被忽略。
  • 我个人喜欢我的代码在不止一个相同的测试输入上工作。 OP 在对该问题的评论中陈述了以下内容:'我正在解析一个可能包含任何类型输入的字符串块。 (我正在解析的字符串)可以来自很多地方,因此我无法预测它将包含什么。'
  • 还不错;那么您对该评论的回复是准确的。可能使用极其复杂的后向正则表达式(查找搜索子字符串,然后向后查找以查找字符串的开头或句点后的第一个字母以及一个或多个未立即以已知缩写开头的空格,然后向前查找找到相同的)但我很确定您创建的任何表达式都会失败一些专门用于测试弱点的输入。
【解决方案2】:

实际上没有必要找到匹配项。由于您正在根据您的搜索模式创建一个新字符串,因此如果您只需要 count 个搜索字符串的出现次数就足够了。如果您愿意,可以用更快的子字符串计数算法替换正则表达式。

string source = "Today is friday! I'm am having trouble programming this. Today is friday! Tomorrow is saturday. Today is friday!";
string searchPattern = "Today is friday!";
int count = Regex.Matches(source, searchPattern).Count;
string result = string.Concat(Enumerable.Repeat(searchPattern, count));

【讨论】:

  • 这只是一个不好的例子,在 cmets 中有一个澄清。不过,这不会捕捉到他想要的句子。
【解决方案3】:

这是一种非 LINQ 方法:

string str = "Today is friday! I'm am having trouble programming this. Today is friday! Tomorrow is saturday. Today is friday!";

StringBuilder sb = new StringBuilder();
int index = 0;
do
{
    index = str.IndexOf("Today is friday!", index);
    if (index != -1)
    {
        sb.Append("Today is friday!");
        index++;
    }
} while (index != -1);

string repeats = sb.ToString();

【讨论】:

    【解决方案4】:

    正则表达式

    查找:

    .*?(Today is friday).*?(?=\1|$)
    

    替换:

    $1
    

    说明

    .*?                 # match everything before an occurrence of the sentence
    (Today is friday!)  # match the sentence
    .*?                 # match everything after the sentence...
    (?=\1|$)            # ...up to the next occurrence or end of the string
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-20
      • 2015-12-23
      • 2022-12-15
      • 2013-03-22
      相关资源
      最近更新 更多