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

geo*_*ory 175 excel-formula

有没有一种有效的方法来使用基函数识别字符串中的最后一个字符/字符串匹配?即不是最后一个字符/字符串字符串,但字符/字符串最后出现的位置一个字符串. Search并且find两者都是从左到右工作所以我无法思考如何在没有冗长的递归算法的情况下应用.而这个解决方案现在似乎已经过时了.

tig*_*tar 332

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

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

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

=FIND("@",SUBSTITUTE(A1,"\","@",(LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))/LEN("\")))
Run Code Online (Sandbox Code Playgroud)

这告诉我们最正确的\是字符24.它通过查找"@"并用"@"替换最后一个"\"来实现.它通过使用确定最后一个

(len(string)-len(substitute(string, substring, "")))\len(substring)
Run Code Online (Sandbox Code Playgroud)

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

=FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))
Run Code Online (Sandbox Code Playgroud)

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

=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))
Run Code Online (Sandbox Code Playgroud)

这是没有尾随\的文件夹路径

=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))-1)
Run Code Online (Sandbox Code Playgroud)

并获得文件名:

=MID(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))
Run Code Online (Sandbox Code Playgroud)

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

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))
Run Code Online (Sandbox Code Playgroud)

  • 头部旋转; 头部纺纱; 头部旋转; "好吧 - 不想在没有理解的情况下使用它,所以......嗯,好吧,嗯......等什么?哇!真的吗?那是天才!我有信心在几个小时内我就不会想到这一点如果不是几天或几周!" - 遗憾的是,+ 1,因为我自己很难做到+5或+10 ---如果你是卡住的解释:(使用例子)`SUBSTITUTE`所有(3)``\`的实例`什么都没有(将字符串的长度缩短3) - >````(第3个)是最后一个; 用独特的东西取而代之,并"找到"那个独特角色的位置......真棒......谢谢! (22认同)
  • 这很聪明.只需要注意该单元格还没有包含"@",否则你需要使用其他东西.您可以使用`= ISNUMBER(SEARCH("@",A1))`,[由@ gwin003提出]检查(http://stackoverflow.com/questions/18617175/excel-check-if-a-cell-contains -a-子). (5认同)
  • 非常感谢你提取最后一次出现的所有内容的最后一个选项,因为大多数时候我一直在寻找"字符串y中字符串x的最后一次出现",我的最终目标实际上是将所有内容都放到了最后一次发生的权利. (2认同)
  • 而不是"@",我使用[CHAR(9)](http://superuser.com/a/402326)(制表符),因为我的数据最初来自制表符分隔文件,我保证它不会在我的数据中. (2认同)
  • 对于同一答案的不同解释:https://superuser.com/a/680776 (2认同)

小智 26

如何创建自定义函数并在公式中使用它?VBA具有内置功能,InStrRev可以完全满足您的需求.

把它放在一个新模块中:

Function RSearch(str As String, find As String)
    RSearch = InStrRev(str, find)
End Function
Run Code Online (Sandbox Code Playgroud)

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

=LEFT(B1,RSearch(B1,"\"))
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常简单但有效的解决方案。如果您可以在项目中使用一些 VBA,请使用这个。 (3认同)

Jvd*_*vdV 8

新版本的 excel 带来了新功能和新方法。虽然它可以在旧版本中复制(但我以前从未见过),但当拥有 Excel O365 时,可以使用:

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),1)="Y"))
Run Code Online (Sandbox Code Playgroud)

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

=MATCH(2,1/(MID(A1,SEQUENCE(LEN(A1)),2)="YY"))
Run Code Online (Sandbox Code Playgroud)
| 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        |
Run Code Online (Sandbox Code Playgroud)

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


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

=MATCH(2,1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"))
Run Code Online (Sandbox Code Playgroud)

通过 输入CtrlShiftEnter,或使用内联INDEX来摆脱隐式交集:

=MATCH(2,INDEX(1/(MID(A2,ROW(A1:INDEX(A:A,LEN(A2))),1)="Y"),))
Run Code Online (Sandbox Code Playgroud)

  • 我认为这现在继承了蜱虫,尽管完整的历史荣誉属于@tigeravatar的长期解决方案/sf/answers/1303240431/ (2认同)

小智 6

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

=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))
Run Code Online (Sandbox Code Playgroud)

如果用作分隔符的字符是空格"",那么公式必须更改为:

=SUBSTITUTE(RIGHT(SUBSTITUTE(A1," ",REPT("{",LEN(A1))),LEN(A1)),"{","")
Run Code Online (Sandbox Code Playgroud)

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


小智 5

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

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

=IFERROR(FIND(CHAR(1);SUBSTITUTE(A1;"_";CHAR(1);LEN(A1)-LEN(SUBSTITUTE(A1;"_";"")));0)
Run Code Online (Sandbox Code Playgroud)

由内而外解释;

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"
Run Code Online (Sandbox Code Playgroud)

希望这是有帮助的。