是否有一种有效的方法来识别字符串中使用基函数的最后一个字符/字符串匹配?也就是说,不是字符串的最后一个字符/字符串,而是字符/字符串在字符串中最后出现的位置。搜索和查找都从左到右工作,所以我不知道如何应用没有冗长的递归算法。现在看来,这种解决方案已经过时了。


当前回答

如何创建一个自定义函数并在您的公式中使用它?VBA有一个内置的函数,InStrRev,它所做的正是您正在寻找的。

把这个放到一个新模块中:

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

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

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

其他回答

如果您只查找字符“~”的最后一个实例的位置,那么 = len(替代(字符串 ,"~",""))+ 1

我确信有一个版本将与字符串的最后一个实例一起工作,但我必须回去工作。

新答案| 31-3-2022:

更新的功能会带来更短的答案。在编写测试版时,我们可以使用TEXTBEFORE(),但在不久的将来可能会广泛使用:

=LEN(TEXTBEFORE(A2,B2,-1))+1

这里的技巧是,第3个形参告诉函数检索我们在第二个形参中给出的子字符串的最后一次出现。在编写此函数时,默认情况下该函数仍然是区分大小写的,可以由可选的第4个参数处理。


原答案| 17-6-2020:

新版本的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"))

通过CtrlShiftEnter输入,或者使用内联INDEX来消除隐式交集:

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

我来晚了一点,但也许这个能帮上忙。问题中的链接使用了类似的公式,但我的链接使用IF()语句来消除错误。

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

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

公式:

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

结果:14

首先,

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, FALSE,14,FALSE,FALSE.....}

最后的

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

返回数组的最大值:14

这个公式的优点是简短,相对容易理解,并且不需要任何唯一的字符。

缺点是需要使用Ctrl+Shift+Enter和字符串长度的限制。这可以通过如下所示的变化来解决,但该变化使用OFFSET()函数,这是一个volatile(读取:slow)函数。

不知道这个公式的速度是多少。

变化:

=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!

在VBA中一个简单的方法是:

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

如何创建一个自定义函数并在您的公式中使用它?VBA有一个内置的函数,InStrRev,它所做的正是您正在寻找的。

把这个放到一个新模块中:

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

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

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