使用 excel 公式删除多个子字符串的匹配字符串
Remove matching strings by multiple substrings using excel formula
如何通过该词的熟悉存根列表删除或替换字符串中熟悉的词?
列表包含约 40 个存根(子字符串)。有了所有这些,我希望替换成百上千个匹配的词。
我对公式求解很感兴趣,因为我已经知道如何做,编码 VBA。
我用 FILTERXML 玩 TEXTJOIN,但它不能用于大存根列表:
公式1.FILTERXML(一一输入存根)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<A><B>"&SUBSTITUTE(A2;" ";"</B><B>")&"</B></A>";"//B[not(contains(., 'auti') or contains(., 'AuTi') or contains(., 'tion') or contains(., 'mpl') or contains(., 'Mpl')or contains(., 'etc'))]"));"")
结果很好,但不幸的是区分大小写,因此所有大写版本(Propercase、UPERCASE、lowercase、MixEdCase)的子字符串都一个接一个地输入,生成一个非常大的公式,由于长度限制(255 个字符)而无法使用.
公式 2.FILTERXML(带大小写翻译)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<T><S>"&SUBSTITUTE(A2;" ";"</S><S>")&"</S></T>";"//S[not(contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'auti')or contains(., 'tion')or contains(., 'mpl')or contains(., 'etc'))]"));"")
结果显然不错,但有一些奇怪的大写匹配缺失(检查附图中的单元格 D14)。为避免这种情况,我可以对每个存根使用翻译 translate(., 'AUTI', 'auti'),'auti')
但长度限制不会让我使用所有列表。
公式 3.FILTERXML(使用 LOWER-ing 所有字符串)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<A><B>"&SUBSTITUTE(LOWER(A2);" ";"</B><B>")&"</B></A>";"//B[not(contains(., 'auti')or contains(., 'tion') or contains(., 'mpl') or contains(., 'etc'))]"));"")
结果不错,但输出字符串完全低了。并且长度限制仍然存在。
我知道 FILTERXML 是完成此任务的好方法,但我不知道如何使用。不幸的是,Xpath 1.0 不允许像 matches()
这样的东西
非常好的问题,但是您正在将 Excel-2019 年制定的公式的功能扩展到它的极限。这是我考虑到 xpath 1.0 的局限性(没有 matches()
和 lists/array 处理:
B1
中的公式:
=TEXTJOIN(" ",,IF(ROW(A:INDEX(A:A,LEN(A2)))=TRANSPOSE(FILTERXML("<x><t>"&TEXTJOIN("</s></t><t>",,IFERROR(ROW(A:INDEX(A:A,COUNTA(FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s"))))&"<s>"&FILTERXML("<t><s>"&SUBSTITUTE(LOWER(A2)," ","</s><s>")&"</s></t>","//s"),""))&"</s></t></x>","//t[.//*[not(contains(., '"&TEXTJOIN("') or contains (., '",,{"auti","tion","mpl","etc"})&"'))]]")),FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s"),""))
我已经针对长度为 3-4 个字符的 40 项数组进行了测试,没有超过 TEXTJOIN()
参数的限制,也没有它可以处理的字符限制。
这是一个 array-entered 公式 (CSE)。
总结一下它的作用:
- 在 space 上拆分您的输入(保持 case-specifications 完整);
- 使用
TEXTJOIN()
创建一个新的输入字符串,以使用另一级别的 xpath childs 为每个单词指定一个索引;
- 对于
FILTERXML()
我们 return 每个不包含您指定的 array-elements 的索引;
- 使用这些数字检索第一步中的所有节点并将它们连接在一起;
- 请注意,这会影响标点符号。
请注意,使用 ms365 的 lambda 辅助函数,这将变得更加容易 REDUCE()
:
=REDUCE(A1,{"auti","tion","mpl","etc"},LAMBDA(a,b,TEXTJOIN(" ",,FILTERXML("<t><s>"&SUBSTITUTE(a," ","</s><s>")&"</s></t>","//s[not(contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), '"&b&"'))]"))))
如何通过该词的熟悉存根列表删除或替换字符串中熟悉的词?
列表包含约 40 个存根(子字符串)。有了所有这些,我希望替换成百上千个匹配的词。
我对公式求解很感兴趣,因为我已经知道如何做,编码 VBA。
我用 FILTERXML 玩 TEXTJOIN,但它不能用于大存根列表:
公式1.FILTERXML(一一输入存根)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<A><B>"&SUBSTITUTE(A2;" ";"</B><B>")&"</B></A>";"//B[not(contains(., 'auti') or contains(., 'AuTi') or contains(., 'tion') or contains(., 'mpl') or contains(., 'Mpl')or contains(., 'etc'))]"));"")
结果很好,但不幸的是区分大小写,因此所有大写版本(Propercase、UPERCASE、lowercase、MixEdCase)的子字符串都一个接一个地输入,生成一个非常大的公式,由于长度限制(255 个字符)而无法使用.
公式 2.FILTERXML(带大小写翻译)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<T><S>"&SUBSTITUTE(A2;" ";"</S><S>")&"</S></T>";"//S[not(contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'),'auti')or contains(., 'tion')or contains(., 'mpl')or contains(., 'etc'))]"));"")
结果显然不错,但有一些奇怪的大写匹配缺失(检查附图中的单元格 D14)。为避免这种情况,我可以对每个存根使用翻译 translate(., 'AUTI', 'auti'),'auti')
但长度限制不会让我使用所有列表。
公式 3.FILTERXML(使用 LOWER-ing 所有字符串)
=IFERROR(TEXTJOIN(" ";;FILTERXML("<A><B>"&SUBSTITUTE(LOWER(A2);" ";"</B><B>")&"</B></A>";"//B[not(contains(., 'auti')or contains(., 'tion') or contains(., 'mpl') or contains(., 'etc'))]"));"")
结果不错,但输出字符串完全低了。并且长度限制仍然存在。
我知道 FILTERXML 是完成此任务的好方法,但我不知道如何使用。不幸的是,Xpath 1.0 不允许像 matches()
这样的东西非常好的问题,但是您正在将 Excel-2019 年制定的公式的功能扩展到它的极限。这是我考虑到 xpath 1.0 的局限性(没有 matches()
和 lists/array 处理:
B1
中的公式:
=TEXTJOIN(" ",,IF(ROW(A:INDEX(A:A,LEN(A2)))=TRANSPOSE(FILTERXML("<x><t>"&TEXTJOIN("</s></t><t>",,IFERROR(ROW(A:INDEX(A:A,COUNTA(FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s"))))&"<s>"&FILTERXML("<t><s>"&SUBSTITUTE(LOWER(A2)," ","</s><s>")&"</s></t>","//s"),""))&"</s></t></x>","//t[.//*[not(contains(., '"&TEXTJOIN("') or contains (., '",,{"auti","tion","mpl","etc"})&"'))]]")),FILTERXML("<t><s>"&SUBSTITUTE(A2," ","</s><s>")&"</s></t>","//s"),""))
我已经针对长度为 3-4 个字符的 40 项数组进行了测试,没有超过 TEXTJOIN()
参数的限制,也没有它可以处理的字符限制。
这是一个 array-entered 公式 (CSE)。
总结一下它的作用:
- 在 space 上拆分您的输入(保持 case-specifications 完整);
- 使用
TEXTJOIN()
创建一个新的输入字符串,以使用另一级别的 xpath childs 为每个单词指定一个索引; - 对于
FILTERXML()
我们 return 每个不包含您指定的 array-elements 的索引; - 使用这些数字检索第一步中的所有节点并将它们连接在一起;
- 请注意,这会影响标点符号。
请注意,使用 ms365 的 lambda 辅助函数,这将变得更加容易 REDUCE()
:
=REDUCE(A1,{"auti","tion","mpl","etc"},LAMBDA(a,b,TEXTJOIN(" ",,FILTERXML("<t><s>"&SUBSTITUTE(a," ","</s><s>")&"</s></t>","//s[not(contains(translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), '"&b&"'))]"))))