如何在不使用 VBA 的情况下在 Excel 中执行反向字符串搜索?
Posted
技术标签:
【中文标题】如何在不使用 VBA 的情况下在 Excel 中执行反向字符串搜索?【英文标题】:How can I perform a reverse string search in Excel without using VBA? 【发布时间】:2010-09-25 21:39:14 【问题描述】:我有一个包含字符串列表的 Excel 电子表格。每个字符串由几个单词组成,但每个字符串的单词数量不同。
使用内置 Excel 函数(无 VBA),有没有办法隔离每个字符串中的最后一个单词?
例子:
你被归类为人类吗? -> 人类? 否定,我是肉冰棒->冰棒 阿齐兹!光! -> 光!【问题讨论】:
我想知道为什么你有人为的无 VBA 约束? 我可以很容易地用 VBA 解决它,但我很好奇是否有非 VBA 解决方案。 VBA 往往会对大型数据集造成性能损失。 像往常一样,有两个答案确实很突出,我很难决定选择哪一个作为正确答案。在这种情况下,Jon 和 BradC(在 Brad 的帮助下)都提出了正确、可行的解决方案。 我选择了 BradC 的解决方案,因为它似乎是两者中更优雅的一个,并且他提供了对该功能的方便解释。 使用函数你刚刚处理了数据——但是“优雅”——使用 vba 你可以收获“旋风”或创造“天堂”。您选择的:由您决定。有时,“保持简单”是最优雅的解决方案。 【参考方案1】:这个已经过测试并且可以工作(基于 Brad 的原始帖子):
=RIGHT(A1,LEN(A1)-FIND("|",SUBSTITUTE(A1," ","|",
LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))
如果您的原始字符串可以包含管道“|”字符,然后用不会出现在您的源中的其他字符替换上面的两个字符。 (我怀疑 Brad 的原文被破坏了,因为翻译中删除了一个不可打印的字符。
奖励:它是如何工作的(从右到左):
LEN(A1)-LEN(SUBSTITUTE(A1," ",""))
- 原始字符串中的空格计数SUBSTITUTE(A1," ","|", ... )
- 仅将 final 空格替换为 |
FIND("|", ... )
- 查找绝对位置替换 |
(这是最后一个空格)Right(A1,LEN(A1) - ... ))
– 返回之后的所有字符 |
编辑:考虑源文本不包含空格的情况,将以下内容添加到公式的开头:
=IF(ISERROR(FIND(" ",A1)),A1, ... )
现在制作整个公式:
=IF(ISERROR(FIND(" ",A1)),A1, RIGHT(A1,LEN(A1) - FIND("|",
SUBSTITUTE(A1," ","|",LEN(A1)-LEN(SUBSTITUTE(A1," ",""))))))
或者您可以使用其他版本的=IF(COUNTIF(A1,"* *")
语法。
当原始字符串可能在最后一个位置包含空格时,在计算所有空格时添加一个修剪函数:使函数如下:
=IF(ISERROR(FIND(" ",B2)),B2, RIGHT(B2,LEN(B2) - FIND("|",
SUBSTITUTE(B2," ","|",LEN(TRIM(B2))-LEN(SUBSTITUTE(B2," ",""))))))
【讨论】:
感激不尽。也需要字符串的其余部分,因此只需将 =RIGHT 更改为 =LEFT 并删除 LEN(A1)- 即可让我得到其余部分。但是感谢您完成所有最初的腿部工作:) +1:我必须记住“LEN(A1)-LEN(SUBSTITUTE(A1," ",""))" 获取字符实例数的技巧跨度> 优秀的解决方案!唯一的问题是 Excel 本地化了函数名称,因此您需要为非英文 Excel 重新编写公式。以下是俄语版本的重写变体: =ПРАВСИМВ(A1;ДЛСТР(A1)-ПОИСК("|";ПОДСТАВИТЬ(A1;" ";"|";ДЛСТР(A1)-ДЛСТР(A1)-ДЛСТР(ПОД(СТАВР) " ";""))))) 这个答案在包含连续空格的字符串上中断。 我建议将公式分解为临时列(您可以稍后隐藏它们)。对于调试特殊情况非常有用。【参考方案2】:这是我成功使用的技术:
=TRIM(RIGHT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))
要获取字符串中的第一个单词,只需从 RIGHT 更改为 LEFT
=TRIM(LEFT(SUBSTITUTE(A1, " ", REPT(" ", 100)), 100))
另外,将 A1 替换为包含文本的单元格。
【讨论】:
为我工作 - 只是用我的分隔符替换了第一个" "
。如果我没记错的话,这两个100
s 似乎将其限制为 100 个字符的字符串
如果我们使用不同的分隔符,我们也需要在最后去掉它,例如=TRIM(SUBSTITUTE(RIGHT(SUBSTITUTE(A1, ".", REPT(".", 100)), 100), ".", ""))
非常聪明的方法。它的作用是用 100 个空格替换每个空格,然后返回最后 100 个字符,不带前导/尾随空格。
@Benjineer 我认为它适用于超过 100 个字符的字符串。 100 个字符限制了单个单词的大小。您正在使用右侧(或左侧)一百个字符.....如果一个 101 个字符长的单词您会遇到问题,但是如果一个总共 100 个字符的字符串......有 3 个空格......会是填充到大约 400 个字符的字符串并且仍然可以工作。致 Jerry Beaucaire - 非常优雅,谢谢。【参考方案3】:
Jerry 答案的更强大版本:
=TRIM(RIGHT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(TRIM(A1))))
无论字符串的长度、前导或尾随空格或其他任何内容如何,它都有效,而且它仍然非常简短。
【讨论】:
这是一个很好的公式。我将公式修改为=TRIM(RIGHT(SUBSTITUTE(TRIM(A1), ".", REPT(" ", LEN(TRIM(A1)))), LEN(TRIM(A1))))
以获取文件扩展名。
还有一个SUBSTITUTE
允许它适用于任何字符,而不仅仅是空格。 =TRIM(SUBSTITUTE(RIGHT(SUBSTITUTE(TRIM(A1),"/",REPT("/",LEN(TRIM(A1)))),LEN(TRIM(A1))),"/",""))
,其中“/”是分隔符。
@Joefinkle,这是一个非常简洁和智能的解决方案。它工作得很好,只是提到如果分隔符是一个字符串,它在所有情况下都不能很好地工作,这里是一个分隔符的例子:" ; "
(一个被空格包围的分号),输入值:"Technology Sprint 24 ; Sprint 4"
它返回:"; Sprint 4"
。我正在使用由@PProteus 修改的解决方案。
如果分隔符是一个字符串,一个可能的解决方法是用一些特殊字符替换它,例如在@PProteus 公式中将TRIM(A1)
替换为:TRIM(SUBSTITUTE(A1, "strDelimeter", ";"))
在所有地方,按顺序有一个新的字符分隔符:";"
甚至更好地使用char()
函数来查找一些真正意想不到的字符。
@PProteus 在添加第二个SUBSTITUTE
后,您不需要TRIM
函数,用于一般情况的单字符解决方案。该公式提供了消除这部分的预期结果:=SUBSTITUTE(RIGHT(SUBSTITUTE(TRIM(A1),";",REPT(";",LEN(TRIM(A1)))),LEN(TRIM(A1))),";","")
【参考方案4】:
我在 google 上找到了this,在 Excel 2003 中进行了测试,它适用于我:
=IF(COUNTIF(A1,"* *"),RIGHT(A1,LEN(A1)-LOOKUP(LEN(A1),FIND(" ",A1,ROW(INDEX($A:$A,1,1):INDEX($A:$A,LEN(A1),1))))),A1)
[编辑] 我没有足够的代表发表评论,所以这似乎是最好的地方...BradC 的答案也不适用于尾随空格或空单元格... [第二次编辑] 实际上,它也不适用于单个单词...
【讨论】:
最接近的解决方案,但我会抛出一个 Trim() 因为尾随空格会破坏它。 是的,可能最容易在中间单元格中修剪(),然后将上述公式应用于中间单元格。此外,如果单元格恰好为空,则吐出 0,因此也可以用 isblank() 包裹【参考方案5】:=RIGHT(TRIM(A1),LEN(TRIM(A1))-FIND(CHAR(7),SUBSTITUTE(" "&TRIM(A1)," ",CHAR(7),
LEN(TRIM(A1))-LEN(SUBSTITUTE(" "&TRIM(A1)," ",""))+1))+1)
这是非常强大的——它适用于没有空格、前导/尾随空格、多个空格、多个前导/尾随空格的句子......我使用 char(7) 作为分隔符而不是竖线“| "以防万一这是所需的文本项。
【讨论】:
在 excel 2010 中为我工作。谢谢【参考方案6】:这是非常干净和紧凑的,而且效果很好。
=RIGHT(A1,LEN(A1)-MAX(IF(MID(A1,ROW(1:999),1)=" ",ROW(1:999),0)))
它不会因为没有空格或一个单词而出现错误陷阱,但这很容易添加。
编辑: 这可以处理尾随空格、单个单词和空单元格场景。我还没有找到破解它的方法。
=RIGHT(TRIM(A1),LEN(TRIM(A1))-MAX(IF(MID(TRIM(A1),ROW($1:$999),1)=" ",ROW($1:$999),0)))
【讨论】:
酷。这是数组函数的一个非常有趣的用法!没想到隔了这么久还能得到另一个答案。谢谢分享。【参考方案7】:=RIGHT(A1,LEN(A1)-FIND("`*`",SUBSTITUTE(A1," ","`*`",LEN(A1)-LEN(SUBSTITUTE(A1," ","")))))
【讨论】:
你测试了吗?不适用于“你被归类为人类吗?” 不,它不起作用。不过有一些有趣的元素。 LEN(A1)-LEN(SUBSTITUTE(A1," ","") 为您提供字符串中的空格数。 这是一个有趣的功能。太糟糕了,它不起作用。我喜欢能够计算空格数的技巧。 @Brad:我编辑了您的帖子以显示 * 字符。原件没有正确打印。有了这些,它确实有效。 +1【参考方案8】:要添加到 Jerry 和 Joe 的答案中,如果您想在可以使用的最后一个单词之前找到文本:
=TRIM(LEFT(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))), LEN(SUBSTITUTE(TRIM(A1), " ", REPT(" ", LEN(TRIM(A1)))))-LEN(TRIM(A1))))
在 A1 中使用“我的小猫”会导致“我的小猫”(Joe and Jerry's 会给出“猫”
就像 Jerry 和 Joe 分离最后一个词一样,这将把所有的东西都放在那个词的左边(然后把它修剪回来)
【讨论】:
【参考方案9】:想象一下字符串可以颠倒。然后真的很容易。而不是处理字符串:
"My little cat" (1)
你和你一起工作
"tac elttil yM" (2)
在 A2 中使用 =LEFT(A1;FIND(" ";A1)-1)
,您将得到带有 (1) 的 "My"
和带有 (2) 的 "tac"
,这与 (1) 中的最后一个单词 "cat"
相反。
有一些 VBA 可以反转字符串。我更喜欢公共 VBA 函数ReverseString
。
按照说明安装上述内容。然后在 A1 中使用您的字符串,例如 "My little cat"
和 A2 中的此函数:
=ReverseString(LEFT(ReverseString(A1);IF(ISERROR(FIND(" ";A1));
LEN(A1);(FIND(" ";ReverseString(A1))-1))))
您会在 A2 中看到 "cat"
。
上述方法假设单词由空格分隔。 IF
子句适用于包含单个单词的单元格 = 单元格中没有空格。注意:TRIM
和 CLEAN
原始字符串也很有用。原则上,它将整个字符串从 A1 反转过来,并简单地在反转后的字符串中找到与最后一个(反转的)单词(即"tac "
)相邻的第一个空格。 LEFT
选择了这个词,另一个字符串反转重建了这个词的原始顺序 (" cat"
)。 FIND
语句末尾的 -1
删除了空白。
这个想法是很容易提取字符串中的第一个(!)单词,LEFT
和 FIND
是第一个空格。但是,对于最后一个(!)字,当您尝试这样做时,RIGHT
函数是错误的选择,因为不幸的是 FIND 没有您要分析字符串的方向的标志。
因此整个字符串被简单地颠倒了。 LEFT
和 FIND
正常工作,但提取的字符串相反。但是,一旦您知道如何反转字符串,他就没什么大不了了。公式中的第一个 ReverseString
语句完成了这项工作。
【讨论】:
这比这里的所有其他选项都简单得多,非常感谢!!为什么 Find 不能有反向查找或替代 - 我似乎记得与使用负数进行反向搜索有关,但显然不是 vba.... OP 要求没有 VBA。 这也太疯狂了!如果您打算使用 VBA,您可以轻松地进行反向查找【参考方案10】:=LEFT(A1,FIND(IF(
ISERROR(
FIND("_",A1)
),A1,RIGHT(A1,
LEN(A1)-FIND("~",
SUBSTITUTE(A1,"_","~",
LEN(A1)-LEN(SUBSTITUTE(A1,"_",""))
)
)
)
),A1,1)-2)
【讨论】:
【参考方案11】:复制到一列中,选择该列然后首页 > 编辑 > 查找和选择,替换:
全部替换.
星号后面有一个空格。
【讨论】:
请注意,* 在 excel 搜索中是一个(贪婪的)通配符,因此它会匹配最后一个空格之前的所有内容,并将其替换为空【参考方案12】:我翻译成 PT-BR,因为我也需要这个。
(请注意,我已将空格更改为\
,因为我只需要路径字符串的文件名。)
=SE(ÉERRO(PROCURAR("\",A1)),A1,DIREITA(A1,NÚM.CARACT(A1)-PROCURAR("|", SUBSTITUIR(A1,"\","|",NÚM.CARACT(A1)-NÚM.CARACT(SUBSTITUIR(A1,"\",""))))))
【讨论】:
我不知道如何用葡萄牙语阅读 Excel,所以我不得不相信你的话 :)【参考方案13】:实现此目的的另一种方法如下
=IF(ISERROR(TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14))))),TRIM(D14),TRIM(MID(TRIM(D14),SEARCH("|",SUBSTITUTE(TRIM(D14)," ","|",LEN(TRIM(D14))-LEN(SUBSTITUTE(TRIM(D14)," ","")))),LEN(TRIM(D14)))))
【讨论】:
【参考方案14】:你也可以通过反转字符串并找到第一个空格来实现这一点
=MID(C3,2+LEN(C3)-SEARCH(" ",CONCAT(MID(C3,SEQUENCE(LEN(C3),,LEN(C3),-1),1))),LEN(A1))
-
反转字符串
CONCAT(MID(C3,SEQUENCE(LEN(C3),,LEN(C3),-1),1))
-
在反向字符串中查找第一个空格
SEARCH(" ",...
-
从字符串长度中取出在反转字符串中找到的空格位置并返回该部分
=MID(C3,2+LEN(C3)-SEARCH...
【讨论】:
【参考方案15】:我也有这样的任务,完成后,使用上面的方法,我想到了一个新方法:你为什么不这样做:
-
反转字符串(“string one”变成“eno gnirts”)。
使用旧的 Find(从左到右硬编码)。
再次将其反转为可读字符串。
这听起来怎么样?
【讨论】:
当然。但是如何在 Excel 中反转字符串呢?以上是关于如何在不使用 VBA 的情况下在 Excel 中执行反向字符串搜索?的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法在没有 VBA 的情况下在 Excel 中连接两个数组? [复制]
如何在仍可以更改工作表中的值的情况下在vba excel中执行Do Event计时器?
在不使用 VBA 的情况下突出显示 Excel 中的活动行/列?
如何在不使用 AudioQueueRef 的情况下在 AudioQueue 中设置音量?