如何在Excel中从具有特定条件的string中查找子string

我有这样的logging

A Result Hello AP#12/22 Welcome AP#12 Thanks AP#123-21 AP#123 No problem AP#111 AP#111 

所以你可以看到我需要从string的AP代码。 它不能包含 – 或/部分。

注意:

AP代码可以是任何数字的数字

它可以出现在最后或开始

AP代码可以跟随/或 – 或任何其他特殊符号,如:或任何其他。

所以我需要一个通用的公式,而不是检查每个特殊字符(/, – ,:)来获取AP代码。

我想实现这一点,而不使用VB。

可能不是最有效的解决scheme…但这是一种没有VBA的方法:(为了可读性,添加了换行符)

 = "AP#"&MID(MID(A1,FIND("AP#",A1)+3,999),1, MAX((ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,999),{1,2,3},1)+0)+0)*{1,2,3})) 

编辑

稍微好一些的解决scheme:

 = MID(A1,FIND("AP#",A1), MAX(ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,999),{1,2,3},1)+0)*{1,2,3})+3) 

编辑 (再次)

正如在评论中指出的,这并没有考虑到AP#1-1这样的东西。 这里是更新的公式,将考虑到这一点:

 = MID(A1,FIND("AP#",A1),IFERROR(MATCH(FALSE, ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,3),{1,2,3},1)+0),0),4)+2) 

按照要求,这是这个公式的工作原理。 我会一步一步分解它。 这是一个相当长的解释,但如果你只是一步一个脚印,我认为你应该能够理解整个公式。 我将从内部解释发生了什么事情。

FIND("AP#",A1)返回FIND("AP#",A1)的字符索引号,其中AP#的第一个实例出现在A1

为了简单起见,我将在下一步中将FIND("AP#",A1)称为<x1>

MID(A1,<x1>+3,3)返回在AP#后立即出现的A1中的3个字符。 它只返回3个字符,因为从原来的问题,你说最多3个号码可以出现在AP#

(快速注意:本来我把公式的这部分作为MID(A1,<x1>+3,999)但做了这个解释之后,我意识到999可以减less到MID(A1,<x1>+3,999)仍然可以工作,只是3更简单使配方更有效。)

我将在下一步中将这个值MID(A1,<x1>+3,3)称为<x2>

MID(<x2>,{1,2,3},1)实质上是将3个字符的string<x2>转换为3个string的数组 ,每个string1个字符长。 换句话说,如果<x2>是(例如) "1-2" ,则意味着MID(<x2>,{1,2,3},1){"1","-","2"} 。 为了分别分析每个字符,需要将3个字符的string转换为1×3的单个字符数组。

我将在下一步中将MID(<x2>,{1,2,3},1)称为<x3>

看起来像一个简单的步骤,但这里有很多事情要做。 请记住, <x3>仍然是一个string数组,而不是数字 (即使它们看起来像数字)。 +0会将所有看起来像数字的string转换为数字,并将所有看起来不像数字的string转换为错误值。 (在这种情况下, #VALUE!

坚持我们同样的例子, {"1","-","2"}+0将等于{1,#VALUE!,2}

我将在下一步中将<x3>+0称为<x4>

MATCH(FALSE,ISNUMBER(<x4>),0)返回<x4>的第一个索引,它不是一个数字。 这里的想法是find第一个非数字的索引,然后包括所有索引(减一)。

坚持我们的例子, MATCH(FALSE,ISNUMBER({1,#VALUE!,2}),0)将返回2 ,因为{1,#VALUE!,2}中的第二个索引是第一个索引一个号码。

我将在下一步中将MATCH(FALSE,ISNUMBER(<x4>),0)称为<x5>

<x4>中的所有值都可能是数字,在这种情况下<x5>将返回错误,因为它找不到非数字的匹配。 IFERROR(<x5>,4)解决了这个问题。 如果<x5>中的所有值都是数字,则返回值4 。 返回4的原因是因为我们基本上说AP#后面的所有3个字符都是数字,所以AP#之后我们考虑的第一个索引就是第四个索引。

我将在下一步中将IFERROR(<x5>,4)称为<x6>

<x6>+2可能看起来像一个奇怪的计算,它是,所以我会写一个不同的方式,会更有意义: (<x6>-1)+3

请记住<x6>代表的是:这是AP# 3个string中出现的第一个非数字的索引。 因此, <x6>-1是在AP#之后包含的字符数。

现在,为什么要添加3? (<x6>-1)+3必须在AP#本身包含3个字符。 这将在下一步中有意义。

我将在下一步中将<x6>+2称为<x7>

MID(A1,FIND(AP#,A1),<x7>)返回stringA1的一部分,从AP#中的A开始,跨越<x7>字符。 而且<x7>多大? 然而, AP#代码中有很多数字,再加上3(再次,我们必须加3来包含3个AP#字符本身在计算中。)

这是整个计算。

想想看,你可能想要在整个计算过程中包装一个IFERROR ,以处理在string中找不到AP#的情况,例如:

 = IFERROR(MID(A1,FIND("AP#",A1),IFERROR(MATCH(FALSE, ISNUMBER(MID(MID(A1,FIND("AP#",A1)+3,3),{1,2,3},1)+0),0),4)+2),"no match") 

但是真的那是你的电话。 我不确定这是否有必要。

考虑以下用户定义的function:

 Public Function FindAPcode(s As String) As String Dim L As Long, CH As String, i As Long, j As Long FindAPcode = "" L = Len(s) If L = 0 Then Exit Function j = InStr(1, s, "AP#") + 3 If j = 3 Then Exit Function FindAPcode = "AP#" For i = j To L CH = Mid(s, i, 1) If IsNumeric(CH) Then FindAPcode = FindAPcode & CH Else Exit Function End If Next i End Function 

在这里输入图像描述

用户定义的函数(UDF)非常易于安装和使用:

  1. ALT-F11调出VBE窗口
  2. ALT-I ALT-M打开一个新的模块
  3. 粘贴东西,closuresVBE窗口

如果保存工作簿,则UDF将随之保存。 如果您在2003年以后使用的是Excel版本,则必须将该文件另存为.xlsm而不是.xlsx

要删除UDF:

  1. 如上所示调出VBE窗口
  2. 清除代码
  3. closuresVBE窗口

从Excel中使用UDF:

= myfunction的(A1)

要了解有关macros的更多信息,请参阅:

http://www.mvps.org/dmcritchie/excel/getstarted.htm

http://msdn.microsoft.com/en-us/library/ee814735(v=office.14).aspx

有关UDF的具体信息,请参阅:

http://www.cpearson.com/excel/WritingFunctionsInVBA.aspx

macros必须启用这个工作!