在一个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}
- 正好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(或模式)。 在B5
input公式=MID($B$2,1,1)
来查找您正在查找的起始字符。 在B6
input=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