Excel:字符串中的最后一个字符/字符串匹配

时间:2013-09-04 15:02:05

标签: excel-formula

是否有一种使用基本函数识别字符串中最后一个字符/字符串匹配的有效方法?即不是字符串的最后一个字符/字符串 ,而是字符串/字符串的最后一次出现 字符串。 Searchfind都是从左到右工作的,因此我无法在没有冗长的递归算法的情况下思考如何应用。 this solution现在似乎已经过时了。

12 个答案:

答案 0 :(得分:320)

我想我明白你的意思。比方说,你想要在下面的字符串中最右边的\(存储在单元格A1中):

驱动器:\文件夹\子文件夹\ FILENAME.EXT

要获得最后一个\的位置,您将使用以下公式:

=FIND("@",SUBSTITUTE(A1,"\","@",(LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))/LEN("\")))

它告诉我们最右边的\是字符24.它通过查找“@”并用“@”代替最后一个“\”来实现。它使用

确定最后一个
(len(string)-len(substitute(string, substring, "")))\len(substring)

在这种情况下,子字符串只是“\”,其长度为1,所以你可以在结尾留下除法,只需使用:

=FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))

现在我们可以使用它来获取文件夹路径:

=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))

这是没有尾随\

的文件夹路径
=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))-1)

并获得文件名:

=MID(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))

但是,这是一个替代版本,可以将特定字符的最后一个实例的所有内容放在一起。因此,使用我们的相同示例,这也将返回文件名:

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))

答案 1 :(得分:26)

如何创建自定义函数并在公式中使用它? VBA有一个内置函数InStrRev,它完全符合您的需求。

将它放在一个新模块中:

Function RSearch(str As String, find As String)
    RSearch = InStrRev(str, find)
End Function

你的函数看起来像这样(假设原始字符串在B1中):

=LEFT(B1,RSearch(B1,"\"))

答案 2 :(得分:6)

tigeravatar和Jean-FrançoisCorbett建议使用此公式生成最后一次出现的“\”字符的字符串

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))

如果用作分隔符的字符是空格“”,则必须将公式更改为:

=SUBSTITUTE(RIGHT(SUBSTITUTE(A1," ",REPT("{",LEN(A1))),LEN(A1))),"{","")

无需提及,“{”字符可以替换为文本中不会“正常”出现的任何字符。

答案 3 :(得分:4)

随着excel的更新版本,新功能和新方法也随之出现。尽管它可以在旧版本中复制(但我以前从未见过),但是当拥有Excel O365时,可以使用:

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),1)="Y"))

这也可以用于检索(重叠)子字符串的最后位置:

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),2)="YY"))

| Value  | Pattern | Formula                                        | Position |
|--------|---------|------------------------------------------------|----------|
| XYYZ   | Y       | =MATCH(2,1/(MID(A2,SEQUENCE(LEN(A2)),1)="Y"))  | 3        |
| XYYYZ  | YY      | =MATCH(2,1/(MID(A3,SEQUENCE(LEN(A3)),2)="YY")) | 3        |
| XYYYYZ | YY      | =MATCH(2,1/(MID(A4,SEQUENCE(LEN(A4)),2)="YY")) | 4        |

虽然这两个都允许我们不再使用任意替换字符,并且允许重叠模式,但“缺点”是数组的使用。


注意: 您可以通过以下任一方法在旧版Excel中强制执行相同的行为

=MATCH(2,1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"))

通过 Ctrl Shift Enter 输入,或使用内联INDEX消除隐式交集:< / em>

=MATCH(2,INDEX(1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"),))

答案 4 :(得分:3)

您可以使用我创建的这个函数来查找字符串中字符串的最后一个实例。

确定已接受的Excel公式有效,但阅读和使用起来非常困难。在某些时候,你必须突破到更小的块,所以它是可维护的。我的下面的函数是可读的,但这是无关紧要的,因为你使用命名参数在公式中调用它。这使得使用起来很简单。

Public Function FindLastCharOccurence(fromText As String, searchChar As String) As Integer
Dim lastOccur As Integer
lastOccur = -1
Dim i As Integer
i = 0
For i = Len(fromText) To 1 Step -1
    If Mid(fromText, i, 1) = searchChar Then
        lastOccur = i
        Exit For
    End If
Next i

FindLastCharOccurence = lastOccur
End Function

我这样用:

=RIGHT(A2, LEN(A2) - FindLastCharOccurence(A2, "\"))

答案 5 :(得分:3)

刚刚提出这个解决方案,不需要VBA;

在我的例子中找到“_”的最后一次出现;

=IFERROR(FIND(CHAR(1);SUBSTITUTE(A1;"_";CHAR(1);LEN(A1)-LEN(SUBSTITUTE(A1;"_";"")));0)

由内而外解释;

SUBSTITUTE(A1;"_";"") => replace "_" by spaces
LEN( *above* ) => count the chars
LEN(A1)- *above*  => indicates amount of chars replaced (= occurrences of "_")
SUBSTITUTE(A1;"_";CHAR(1); *above* ) => replace the Nth occurence of "_" by CHAR(1) (Nth = amount of chars replaced = the last one)
FIND(CHAR(1); *above* ) => Find the CHAR(1), being the last (replaced) occurance of "_" in our case
IFERROR( *above* ;"0") => in case no chars were found, return "0"

希望这有用。

答案 6 :(得分:1)

我参加派对有点晚了,但也许这可能会有所帮助。问题中的链接具有类似的公式,但我使用IF()语句来消除错误。

如果你不害怕Ctrl + Shift + Enter,你可以用数组公式做得很好。

字符串(在单元格A1中): “one.two.three.four”

公式:

{=MAX(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)))}  use Ctrl+Shift+Enter

结果:1​​4

首先,

ROW($1:$99)

返回1到99之间的整数数组:{1,2,3,4,...,98,99}

接下来,

MID(A1,ROW($1:$99),1)

返回目标字符串中找到的1长度字符串数组,然后在达到目标字符串的长度后返回空字符串:{"o","n","e",".",..."u","r","","",""...}

接下来,

IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99))

将数组中的每个项目与字符串“。”进行比较。并返回字符串中字符的索引或FALSE:{FALSE,FALSE,FALSE,4,FALSE,FALSE,FALSE,8,FALSE,FALSE,FALSE,FALSE,FALSE,14,FALSE,FALSE.....}

最后,

=MAX(IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99)))

返回数组的最大值:14

这个公式的优点是它简短,相对容易理解,不需要任何独特的字符。

缺点是需要使用Ctrl + Shift + Enter和字符串长度限制。这可以使用下面显示的变体进行解决,但该变体使用OFFSET()函数,该函数是易失性(读取:慢速)函数。

不确定此配方的速度与其他配方的速度。

变体:

=MAX((MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1)=".")*ROW(OFFSET($A$1,,,LEN(A1)))) works the same way, but you don't have to worry about the length of the string

=SMALL(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd occurrence of the match

=LARGE(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd-to-last occurrence of the match

=MAX(IF(MID(I16,ROW($1:$99),2)=".t",ROW($1:$99))) matches a 2-character string **Make sure you change the last argument of the MID() function to the number of characters in the string you wish to match!

答案 7 :(得分:1)

考虑@SSilk 所做的评论的一部分,我的最终目标确实是让最后一次出现的所有内容一个非常简单公式的替代方法是复制一列(比如说A)字符串和副本(比如ColumnB)应用查找和替换。例如,举例:Drive:\Folder\SubFolder\Filename.ext

Find what

这将返回所选字符的最后一个实例(此处为Filename.ext)之后剩余的内容(此处\),这有时候是目标,并且有助于找到最后一个字符的位置简短的公式如:

=FIND(B1,A1)-1

答案 8 :(得分:0)

在VBA中执行此操作的简单方法是:

YourText = "c:\excel\text.txt"
xString = Mid(YourText, 2 + Len(YourText) - InStr(StrReverse(YourText), "\" ))

答案 9 :(得分:0)

派对很晚,但一个简单的解决方案是使用VBA创建自定义功能。

将功能添加到WorkBook,Worksheet或VBA模块中的VBA

Function LastSegment(S, C)
    LastSegment = Right(S, Len(S) - InStrRev(S, C))
End Function

然后是细胞公式

=lastsegment(B1,"/")
单元格中的

和要在单元格B1中搜索的字符串将填充单元格,其中文本尾随单元格B1中的最后一个“/”。 没有长度限制,没有模糊的公式。 我能想到的唯一缺点是需要一个支持宏的工作簿。

可以通过这种方式调用任何用户VBA函数,以将值返回到单元格公式,包括作为内置Excel函数的参数。

如果你要大量使用这个功能,你需要检查字符不在字符串中的情况,然后字符串是空白等。

答案 10 :(得分:0)

在较新版本的Excel(2013及更高版本)中,快速填充可能是一种简单快速的解决方案,请参见:Using Flash Fill in Excel

答案 11 :(得分:0)

单元格A1 = find/the/position/of/the last slash

执行此操作的简单方法是反转文本,然后照常查找第一个斜杠。现在,您可以获得减去该数字的全文长度。

像这样:

=LEN(A1)-FIND("/",REVERSETEXT(A1),1)+1

这将返回21,即最后一个/

的位置