【问题标题】:Count number of occurrences based on 2 conditions or Regexp根据 2 个条件或 Regexp 计算出现次数
【发布时间】:2013-08-20 19:58:26
【问题描述】:

如何根据

获取某个范围内的出现次数
  1. 正则表达式

  2. 2+ 条件;假设单元格包含“是”和/或“否”

我目前所拥有的:

COUNTIF(B5:O5; "*yes*")

我尝试使用COUNTIF(B5:O5; {"*yes*", "*no*"})COUNTIF(B5:O5; "(*yes*)|(*no*)"),但它们都不起作用。

或者,我如何使用正则表达式计算包含某些域名(yahoo.com、hotmail.com 和 gmail.com)的单元格?例如:

(\W|^)[\w.+\-]{0,25}@(yahoo|hotmail|gmail)\.com(\W|$)

【问题讨论】:

    标签: regex google-sheets countif


    【解决方案1】:

    对您的问题最简单的解决方案(在 Excel 和 Google Docs 中测试)是简单地将几个 countif 公式的结果相加:

    =COUNTIF(B5:O5, "*yes*") + COUNTIF(B5:O5, "*no*")
    

    此表达式将计算带有“是”或“否”的单元格总数。因为它匹配两个表达式,所以它将用“yesno”或“noyes”重复计算一个单元格。您可以尝试使用

    来消除双打
    =COUNTIF(B5:O5, "*yes*") + COUNTIF(B5:O5, "*no*") - COUNTIF(B5:O5, "*no*yes*") - COUNTIF(B5:O5, "*yes*no*")
    

    但是对于noyesno 这样的字符串,你仍然会遇到麻烦。

    但是,Google Docs 中有一个相当聪明的技巧,它可能只是您正在寻找的解决方案的提示:

    =COUNTA(QUERY(A1:A9, "select A where A matches '(.*yes.*)|(.*no.*)'"))
    

    QUERY 函数就像一个小型数据库。在这种情况下,它会查看A1:A9 范围内的表格,并仅选择 A 列中的元素,其中 A 列中的对应元素 matches(在 preg regex 这个词的意义上)后面的表达式 - 在这种情况下, “任何后面跟着yes 后面跟着任何东西,或者后面跟着no 后面跟着任何东西”。在我制作的一个简单示例中,这仅计算一次 yesnoyes - 完全符合您的要求(我认为...)

    现在您的范围B5:O5 有几列宽,只有一行高;这使得使用QUERY 技巧变得困难。不太优雅的东西(但不管范围的形状如何都有效)是这样的:

    =countif(arrayformula(isnumber(find("yes",A1:A9))+isnumber(find("no",A1:A9))),">0")
    

    isnumber 函数的总和充当元素方面的 OR - 不幸的是,常规 OR 函数似乎不适用于数组的单个元素。和以前一样,这会查找包含“yes”或“no”的单元格,并计算包含其中任何一个字符串的单元格。

    【讨论】:

    • 您可以先TRANSPOSE(B5:O5) 再将其发送到QUERY 吗?还是QUERY 对匿名矩阵的列标识符有问题?
    • @Michael 你试过了吗?我现在无法测试它,但我会对答案很感兴趣。
    • 我无法让它工作。不适用于 QUERY(TRANSPOSE(B5:O5), "select A")…, "select col1")QUERY({"foo"; TRANSPOSE(B5:O5)}, "select foo", 1)。它总是抱怨缺少列标识符。 select * 有效,但您不能在 where 子句中使用 *
    • 我再次尝试并让它工作。请参阅below:显然Col1 是“神奇”标识符,它区分大小写。请注意,它在文档示例identifiers 中没有正确的大小写。
    【解决方案2】:

    这在很大程度上受到了Floris's answer 的启发。尤其是见 cmets。如果您 TRANSPOSE 要比较的项目行,QUERY 也适用于水平数据:

    =COUNTA(QUERY(TRANSPOSE(B5:O5), "select * where Col1 matches '.*(yes|no).*'"))
    

    据我所知,Col1 是“特殊的”并且区分大小写!

    【讨论】:

      【解决方案3】:

      NGix 发现的最简单的方法是为这些目的创建一个自定义函数。他们添加了 2 个非常适合他们的方法,并希望它也能对某人有所帮助:

      /**
       * Count if cell value matches any condition ( supports regexp also )
       */
      
      function countCustomMatchOr(data){
        var count = 0;
        for(var i=0; i < data.length; i++){
          for(var j=0; j<data[i].length; j++){
              var cell = data[i][j];
            for(var k=1;k<arguments.length;k++){
              if(typeof arguments[k] == "number"){
                if(arguments[k] == cell) count++;
              } else if(cell.toString().match(arguments[k])) count++;
            }
          }
        }
        return count;
      }
      

      /**
       * Counts value in data range if matches regular expression
       */
      
      function countCustomRegExp(data, reg, flag){
        var rows = data.length, count = 0, re = flag?new RegExp(reg, flag):new RegExp(reg);
        for( var i = 0; i < rows; i++){
          for( var j = 0; j < data[i].length; j++){
            if( data[i][j] != "" && data[i][j].toString().match(re) ){
              count++;
            }
          }
        }
        return count;
      }
      

      要使用它们,只需申请 countCustomRegExp(A2:G3;"yes.*")countCustomMatchOr(A2:G3;"yes";"no")

      【讨论】:

        【解决方案4】:

        我也遇到过同样的问题,如果您不想使用VBA,请尝试在公式中添加SUM=SUM(COUNTIF(B5:O5; {"*yes*", "*no*"}))

        【讨论】:

        • 这在 Google 表格中不起作用。请注意,该问题标有google-docs
        猜你喜欢
        • 2021-10-24
        • 2021-03-23
        • 1970-01-01
        • 2014-10-01
        • 2021-07-14
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多