在Excel中查找字符的第N个实例(无VBA)

时间:2019-03-27 10:19:16

标签: excel excel-formula

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

5 个答案:

答案 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)

这是怎么做-

enter image description here

这里B2Delimiter type,而C2Nth occurrence of the Delimiter。您可以根据需要修改代码。只需更改B2C2

答案 1 :(得分:1)

例如,如果要在单元格 A1 中找到?的第三实例,请尝试:

=FIND(CHAR(1),SUBSTITUTE(A1,"?",CHAR(1),3))

enter image description here

注意:

我们假设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()可以防止DelimiterInstanceNumber中仅出现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)

不确定大型数据库中哪一个效率更高(更快)