【问题标题】:Count how many occurrences of substrings within a string without counting duplicates计算字符串中子字符串的出现次数而不计算重复项
【发布时间】:2017-07-06 14:55:36
【问题描述】:

例如,我有一个术语列表和一个字符串:

var terms = { "programming language", "programming", "language" };

var content = "A programming language is a formal language that "
    + "specifies a set of instructions that can be used to "
    + "produce various kinds of output.";

我可以用Regex.Matches(content, term).Count来统计列表中有4次出现在字符串中:

  • “编程语言”:1次
  • “编程”:1次
  • “语言”:2 次​​li>

但是有重复,应该只有2次。

我当前的解决方案是保存每次出现的开始索引和结束索引,然后与保存的出现进行比较,只要它在范围内并且已经被计数。有没有更好的方法不使用开始和结束索引?

【问题讨论】:

  • 你如何构建你的正则表达式? (programming language|programming|language) 应该做你想做的,如果你做对了。
  • 显示您之前尝试过的内容。
  • 知道了,好的,您是一次性运行正则表达式还是拆分它?如果要拆分它,那很简单,首先运行更具体的正则表达式,然后维护一组已找到的术语的哈希集。如果它要查找的内容包含在哈希集中,请不要运行正则表达式。如果它全部作为一个正则表达式的一部分运行,那么我无法帮助你,尽管我确信可能有办法。
  • @TimSchmelter 因为programming language 算作一个术语,如果我删除它,当前示例将返回 3 次,而不是我预期的 2 次。
  • @TimSchmelter 我认为Count 与累加器一起使用,所以programming 出现一次,language 出现两次,求和后不会返回 3?

标签: c# .net regex string algorithm


【解决方案1】:

根据 cmets 的建议,我有一个使用正则表达式的 simple solution,它应该与精确的整个单词一起使用,即 programming language 可以计算但 programming languages 不能:

var pattern = @"(?<!\S)programming language(?![^\s])|(?<!\S)programming(?![^\s])|(?<!\S)language(?![^\s])";
var count = Regex.Matches(content, pattern).Count;

注意:这种模式只能在programming language 放在programminglanguage 术语之前使用。如果有人可以提供更好的解决方案,请提供。

【讨论】:

  • 您可以使用\b 代替(?&lt;!\S)(?![^\s]) 来检测单词边缘。除此之外,您剩下要做的就是找到一种自动排序搜索词的方法......
  • @Rawling 我是正则表达式的新手,能否请您写一个使用\b 检测边缘的示例?
  • 类似\b(xy|y|z)\b\b 匹配单词字符(字母、数字、下划线)和非单词字符(其他任何字符)之间的点。
猜你喜欢
  • 1970-01-01
  • 2020-02-21
  • 2012-02-12
  • 2012-05-31
  • 2011-03-02
相关资源
最近更新 更多