Regex 一系列单元中子串的高效单元公式计数
我有一个谷歌电子表格,有两列:a列和C列。a列在自己的单元格中有上千行名称/主题,C列在其各个单元格中有数百行,上面的名称/主题以不同的组合出现,每个名称/主题用分号与其他名称/主题分开。这些栏目中的每一个都会在一天中频繁地获得新的条目 作为设置的一个非常简化的视觉示例:Regex 一系列单元中子串的高效单元公式计数,regex,count,google-sheets,formulas,array-formulas,Regex,Count,Google Sheets,Formulas,Array Formulas,我有一个谷歌电子表格,有两列:a列和C列。a列在自己的单元格中有上千行名称/主题,C列在其各个单元格中有数百行,上面的名称/主题以不同的组合出现,每个名称/主题用分号与其他名称/主题分开。这些栏目中的每一个都会在一天中频繁地获得新的条目 作为设置的一个非常简化的视觉示例: **Column A: Names | Column B: Occurrences | Column C: List** A2: Adam | B2: [Blank] | C2: C
**Column A: Names | Column B: Occurrences | Column C: List**
A2: Adam | B2: [Blank] | C2: Charles; Adam
A3: Bob | B3: [Blank] | C3: Adam
A4: Charles | B4: [Blank] | C4: Smith, Charles
A5: Smith, Charles | B5: [Blank] | C5: Bob Evans
A6: Bob Evans | B6: [Blank] | C6: Smith, Charles; Charles; Bob
A7: [etc.] | B7: [Blank] | C7: Bob Evans; Charles; Bob
A8: [etc.] | B8: [Blank] | C8: [etc.]
目前,我使用以下公式计算A列(此处为A2)中的每个字符串作为C列(此处为C2到C7)中的子字符串出现的次数:
=ARRAYFORMULA(IF(A2=”,”,(SUMPRODUCT(REGEXMATCH)(REGEXREPLACE($2:$c7),([\(\)\?))”,“,”,“(\w+),“(\0,1}\s+(\w+),“$1$2”),”*(^(^124;\ s)”和trim(REGEXREPLACE(REGEXREPLACE($A2),([\(\(\)\)\?));”,“,”,“),”,“),”,“,”,(\w+,(\0,1}\s+),“$1242+),”),“),”),”);/code>
这给出了正确的总数,但一旦你扩大规模,它似乎是难以置信的处理繁重;在C列中更改或添加任何一个条目都会导致整个工作表重新计算其数千个条目,并且需要几分钟才能得出新的总数。这里使用了许多REGEXREPLACE值,因为有些条目有“()”和“?”等标点符号,例如“Erōs”、“Olympic Games(第23届:1984年:加利福尼亚州洛杉矶市)”和“Thomas,Aquinas,Saint,1225?-1274”等单元格
我提出的最接近计数的备选方案如下:
=SUMPRODUCT((LEN(C$2:C$7)-LEN(替换(C$2:C$7,A2,”)))/LEN(A2))
测试表明,这个简单得多的公式可以在几秒钟内重新计算整个工作表,但实际上无法正确计算条目数。在上面的C2-C7示例中,“Bob”和“Charles”的总数分别为4和5,因为它没有区分“Bob”和“Bob Evans”或“Charles”和“Smith,Charles”。它应该分别正确地找到2和3
是否有一种有效的方法来调整上述公式或创建一个新的公式来计算所有子字符串,当它们在C列的分号之间时,正确地将总和限制为与a列的精确匹配,而不会导致工作表的计算一次冻结几分钟?正则表达式是我最初选择的路线,但我认为这些操作是它花费这么长时间的原因。试试
B2:
试试
B2:
这可能会让您从正确的方向开始:
=QUERY(C$2:C,"SELECT count(C) WHERE C CONTAINS ('"&A2&"') OR C CONTAINS upper('"&A2&"') OR C CONTAINS lower('"&A2&"')", -1)
这可能会让您从正确的方向开始:
=QUERY(C$2:C,"SELECT count(C) WHERE C CONTAINS ('"&A2&"') OR C CONTAINS upper('"&A2&"') OR C CONTAINS lower('"&A2&"')", -1)
也试试这个:
在某处
Y1:
=QUERY(ARRAYFORMULA)(TRIM(TRANSPOSE)(SPLIT)(CONCATENATE)(splite)(splite)(C2:C6,“;”)&“也试试这个:
在某处
Y1:
=QUERY(ARRAYFORMULA)(TRIM(TRANSPOSE)(SPLIT)(CONCATENATE)(SPLIT(SPLIT)(C2:C6,“;”)&“您可以将其全部简化为大写)。=QUERY(C$2:C,“选择count(C)),其中大写(C)包含大写(“&A2&“)”)
这两种方法在精确计数方面看起来都很有帮助,但在我将其中一个公式放在B1中时,它只能提取“Adam”的数字出现在B2中,而不是为每个列计算一个实例,并在相应的B单元格中显示它们的总和。恐怕我对SQL和Google查询不太熟悉,无法识别问题。简单的修复方法是,查询函数喜欢标记其数据集,因此关闭它的方法是:=Query(C$2:C),选择count(C),其中C包含(“”&A2)&“')或C包含上限(“&A2&“')或C包含下限(“&A2&“')标签计数(C)”),您可以将其全部设置为上限以简化。=QUERY(C$2:C,“选择计数(C),其中上限(C)包含上限(“&A2&“)”)”
这两种方法看起来都非常有助于精确计数,但在我将其中一个公式放入B1时,它只会提取Adam“出现在B2中,而不是计算每个列的实例数,并在相应的B单元格中显示它们的总和。恐怕我对SQL和Google查询不太熟悉,无法识别问题。简单的修复方法是,查询函数喜欢标记其数据集,因此要将其关闭,请执行以下操作:=查询(C$2:C),选择计数(C),其中C包含('“&A2&”)或C包含上限(“&A2&”)或C包含下限(“&A2&”)标签计数(C)”),这太棒了,是的!我唯一的问题是是否有一种方法让它在不返回错误的情况下搜索无限范围。使用($C$2:$C)而不是($C$2:$C$8)会得到一个#值的结果,“Error Function SPLIT parameter 1 value应该是非空的。”我还没有找到将IF语句分层的正确方法来管理它。C$2:INDEX(C$2:C,CountA(C$2:C))
或C$2:C&“
第一种方法的性能更好(如果您能找到如何使用它的话)。如果您只想计算每个唯一实体的数量,请查看下面我的其他解决方案。我相信这样做了;非常感谢您的帮助!这非常好,是的!我唯一的问题是是否有一种方法可以让它搜索无限范围而不返回错误。使用($C$2:$C)而不是($C$2:$C$8)会得到#VALUE的结果,“Error Function SPLIT parameter 1 value应该是非空的。”我还没有找到将IF语句分层的正确方法来管理它。C$2:INDEX(C$2:C,CountA(C$2:C))
或C$2:C&“
第一种方法的性能更好(如果您能找到如何使用它的话)。如果您只想计算每个唯一实体的数量,请查看下面我的其他解决方案。我相信这就成功了;非常感谢您的帮助!漂亮的方法。&“@A.K.它是一个唯一的区分实体。公式需要在文本上有一个唯一的标记,在将它们合并为一个后才能分开。我也可以使用%
或任何其他符号。但是,您的文本中也可能有%
。如果这样,公式将失败。