TL; DR摘要:我想要一个公式,该公式将在字符串中找到第N个“ _
”(对于任何N),并返回其索引;或找到第N个子字符串,以“ _
”分隔。我有VBA来执行此操作,但是速度很慢。
长版: 我正在处理广告活动数据。我的营销人员(很幸运)在广告系列中使用了一致的命名方案。不幸的是,这很长。
广告系列名称仅包含1条我无法通过报告获得的数据。
供参考,广告系列名称的格式为:
ADV_CO_BG_Product_UniqueID_XX_mm.dd.yyyy_mm.dd.yyyy_TYP_NUM
...我有一列约200K(每周增长几百)。
编辑:
重要的是,广告系列名称包含多个部分,_
是它们之间的分隔符。在这种情况下,我需要第9部分,但我需要一个足够灵活的选项,无需添加或删除行即可更改我要定位的部分。
我在其他问题上也看到过使用嵌套公式,例如:
=MID(
Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign],
FIND("_",Data_OLV[@Campaign])+1)
+1)
+1)
+1)
+1)
+1)
+1)
+1,
3)
...但是如果我需要其他位置的东西很难修改。
我有一个称为StringSplit的UDF(请参见下文),它提供了所需的结果,但是它非常慢(并且仅在启用了宏的情况下才起作用,而并不是我的所有听众都这么做)。
是否有更好的方法来做我想做的事情?
Public Function StringSplit(input_ As String, delimiter_ As String, index_ As Integer)
On Error GoTo err
out = Split(input_, delimiter_, -1, vbTextCompare)
StringSplit = out(index_ - 1)
Exit Function
err:
If err.Number = 9 Then
StringSplit = CVErr(xlErrRef)
Exit Function
End If
StringSplit = err.Description
End Function
答案 0 :(得分:2)
我认为这是您要寻找的公式-
=MID(A2, FIND(CHAR(1), SUBSTITUTE(A2, B2, CHAR(1), C2))+1, FIND(CHAR(1), SUBSTITUTE(A2, B2, CHAR(1), C2+1)) - FIND(CHAR(1), SUBSTITUTE(A2, B2, CHAR(1), C2))-1)
这是怎么做-
这里B2
是Delimiter type
,而C2
是Nth occurrence of the Delimiter
。您可以根据需要修改代码。只需更改B2
和C2
。
答案 1 :(得分:1)
例如,如果要在单元格 A1 中找到?的第三实例,请尝试:
=FIND(CHAR(1),SUBSTITUTE(A1,"?",CHAR(1),3))
注意:
我们假设CHAR(1)
没有出现在原始字符串中。
要获取 last 实例,请使用:
=FIND(CHAR(1),SUBSTITUTE(A1,"?",CHAR(1),(LEN(A1)-LEN(SUBSTITUTE(A1,"?","")))))
答案 2 :(得分:0)
如果您是正确的话,您是说收到的数据始终采用您发布的格式,并且您始终希望提取TYP数据。
为什么不在字符串中搜索TYP
,又搜索NUM
,因为它表示以下子数据?
然后,您将得到一个诸如
的公式=TRIM(MID(W20,SEARCH("TYP",W20),SEARCH("NUM",W20)-SEARCH("TYP",W20)))
在此公式中,单元格W20
保存了整个数据字符串。自然,您可以编辑此范围,也可以将整个字符串粘贴到其位置。
编辑
由于OP提到标题字符串不一致:
=TRIM(MID(W20,SEARCH(A1,W20),IF(A2="",LEN(W20),SEARCH(A2,W20)-SEARCH(A1,W20))))
在单元格A1
中,将是必须提取的数据的标题字符串,在本例中为TYP
在单元格A2
中将是下一个子数据的标题字符串。如果为空,则公式将返回使用单元格SEARCH
从第一个A1
函数中找到的所有字符。
答案 3 :(得分:0)
正如伊根·沃尔夫(Egan Wolf)所说,http://exceljet.net/formula/find-nth-occurrence-of-character有一个解决方案
=MID([@[Campaign]],FIND(CHAR(160),SUBSTITUTE([@[Campaign]],"_",CHAR(160),9))+1,4)
或更笼统地说:
=MID(TextToSearch,FIND(CHAR(160),SUBSTITUTE(TextToSearch,Delimiter,CHAR(160),InstanceNumber ))+1,LengthOfDesiredSection)
LengthOfDesiredSection
当然可以通过第一个公式的小节找到,就像这样(为清楚起见添加了换行符):
=MID(TextToSearch,
FIND(CHAR(160),SUBSTITUTE(TextToSearch,Delimiter,CHAR(160),InstanceNumber))+1,
IFERROR(
(FIND(CHAR(160),SUBSTITUTE(TextToSearch,Delimiter,CHAR(160),InstanceNumber+1)-
FIND(CHAR(160),SUBSTITUTE(TextToSearch,Delimiter,CHAR(160),InstanceNumber)))-1,
LEN(TextToSearch)-
FIND(CHAR(160),SUBSTITUTE(TextToSearch,Delimiter,CHAR(160),InstanceNumber))))
IFERROR()
可以防止Delimiter
在InstanceNumber
中仅出现TextToSearch
次的情况。
答案 4 :(得分:0)
找到下划线定界字符串的第n个实例并返回该子字符串的一种方法是使用以下公式:
=TRIM(MID(SUBSTITUTE(A1,"_",REPT(" ",999)),MAX(1,999*(n-1)),999))
其中n
是您要查找的实例。
但是,当然,这要求元素以相同的顺序存在,并且始终存在(或者如果不存在则用下划线代替)。
如果您使用的是带有FILTERXML
函数的Excel版本,则可以使用以下公式:
=INDEX(FILTERXML("<t><s>" & SUBSTITUTE(A1,"_","</s><s>") & "</s></t>","//s"),n)
不确定大型数据库中哪一个效率更高(更快)