在一个Cell Excel中计数模式

我想要你的帮助,我目前正在提取一些数据,现在的事情是我要计算一个特定数量的Call ID,一个Call ID格式是9129572520020000711 。 模式是19个字符,从9开始,以1结尾,我想要统计这个模式在一个单元格中出现的次数

IE这是在一个单元格中的值,我想要统计模式出现的次数。

 1912957252002000071129129545183410000711391295381628700007114912959791875000071159129597085000000711691295892838400007117912958908933000071189129452513730000711 

您可以使用正则expression式简单地使用UDF来解决这个问题。

 Option Explicit Function callIDcount(S As String) As Long Dim RE As Object, MC As Object Const sPat As String = "9\d{17}1" Set RE = CreateObject("vbscript.regexp") With RE .Global = True .Pattern = sPat Set MC = .Execute(S) callIDcount = MC.Count End With End Function 

使用你的例子,这将返回一个8的计数

正则expression式引擎将匹配模式的所有匹配捕获到匹配集合中。 要看有多less人,我们只是返回收集的数量。

如果有必要,简单的修改将允许返回实际的ID。

在这里输入图像说明

正则expression式:

9 \ d {17} 1

 9\d{17}1 
  • 字面上匹配字符“9” 9
  • 匹配一个“数字”(仅ASCII 0-9) \d{17}
    • 正好17次 {17}
  • 字面上匹配字符“1” 1

用RegexBuddy创build

编辑通过TheFizh的post阅读,他认为你可能希望计数包括重叠CallID的。 换句话说,给出:

 9129572520020000711291 

我们看到这包括:

 9129572520020000711 9572520020000711291 

第二个与第一个重叠,但都满足您的要求。

如果这是你想要的,只是改变正则expression式,所以它不会“消耗”匹配:

 Const sPat As String = "9(?=\d{17}1)" 

你将返回15而不是8的结果,这将是非重叠模式。

要用公式解决这个问题,你需要知道:

  • 起始字符
  • 结束字符
  • 您的通话ID的长度

find所有可能的呼叫ID

在这里输入图像说明

B1是你的数字串, B2是你正在寻找的呼叫ID(或模式)。 在B5input公式=MID($B$2,1,1)来查找您正在查找的起始字符。 在B6input=RIGHT($B$2,1)作为结束字符。 在B7 ,对于呼叫ID的长度,input=LEN($B$2)

在列A中,我们将input每个起始字符的位置。 第一个公式在B10中将是一个简单的Find()公式=FIND($B$5,$B$1,1) 。 要查找其他起始字符=FIND($B$5,$B$1,$A10+1)B11的最后一个起始字符后面的位置启动Find()=FIND($B$5,$B$1,$A10+1) 。 复制这个列几十次(或更多)。

在列B中,我们将看看下一个X字符(其中X是呼叫ID的长度)是否符合呼叫ID的标准:

 =IF(MID($B$1,$A10+($B$7-1),1)=$B$6,TRUE,FALSE) 

MID($B$1,$A10+($B$7-1),1)=$B$6检查在这个可能的Call ID末尾的字符末尾的字符是否是我们要查找的结束字符。 $A10+($B$7)计算可能的呼叫ID的位置, $B$6是结束字符。

在列C中,如果匹配,我们可以返回实际的呼叫ID。 这是没有必要find计数, 但稍后会有用 。 只需检查B列中的值是否为True,如果是,则返回计算的string: =IF(B10,MID($B$1,$A10,$B$7),"")

要实际统计有效呼叫ID的数量,请执行呼叫ID列的CountIf()以检查True值的数量: =IF(B10,MID($B$1,$A10,$B$7),"")

如果你不想要所有的#Values! 只是将所有内容都包装在IFERROR(,"")公式中。

查找所有连续的呼叫ID

在这里输入图像说明

但是,其中一些呼叫ID重叠。 假设Call ID不能重叠,我们只需在find的ID的结束字符后面开始search,而不是开始。 在列B中插入“结束位置”列,公式为: =$A10+($C$7-1) ,从B11开始。 改变A11 =FIND($C$5,$C$1,$B10+1)并复制下来。 不要改变A10因为这find了第一个开始的位置,不依赖于任何东西,但原来的文字。

哪些是有效的?

我不知道,这取决于您的呼叫ID的其他标准。 如果你连续收到它们,那么第二种方法是最好的,其他可能的方法是巧合的。 如果没有,那么你将不得不对第一个方法应用一些其他的validation标准, 所以我们为什么要识别每个ID

你的意思是什么如下?

 Sub CallID_noPatterns() Dim CallID As String, CallIDLen As Integer CallID = "9#################1" CallIDLen = Len(CallID) 'the CallID's length 'Say that you want to get the value of "A1" cell and deal with its value Dim CellVal As String, CellLen As Integer CellVal = CStr(Range("A1").Text) 'get its value as a string CellLen = Len(CellVal) 'get its length 'You Have 2 options:- '1-The value is smaller than your CallID length. (Not Applicable) '2-The value is longer than or equal to your CallID length 'So just run your code for the 2nd option Dim i As Integer, num_checks, num_patterns i = 0 num_patterns = 0 'imagine both of them as 2 arrays, every array consists of sequenced elements 'and your job is to take a sub-array from your value, of a length ' equals to CallID's length 'then compare your sub-array with CallID num_checks = CellLen - CallIDLen + 1 If CellLen >= CallIDLen Then For i = 0 To num_checks - 1 Step 19 For j = i To num_checks - 1 If Mid(CellVal, (j + 1), CallIDLen) Like CallID Then num_patterns = num_patterns + 1 Exit For End If Next j Next i End If 'Display your result MsgBox "Number of Patterns: " & Str(num_patterns) End Sub