这可以通过 Excel 2016 及更高版本中的单个公式来完成。
虽然 pnuts 的解决方案列出了要去除的显式字符,但此解决方案列出了显式有效的字符。
假设您的脏数据位于 A 列中。假设您希望干净的数据位于 B 列中。
在单元格 B1 中使用下面最后一个公式。要将公式输入到单元格 B1 中,请执行以下操作:
- 单击单元格 B1
- 点击进入编辑栏
- 粘贴公式
- 按 CTRL+Shift+Enter <-- 重要步骤
根据需要复制单元格 B1 并将其粘贴到 B 列中。
首先,这是一个简短的示例来解释发生了什么:
=TEXTJOIN("",TRUE,
IFs(
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "t", "t",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "e", "e",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "s", "s",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "T", "T",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "E", "E",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "S", "S",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = "2", "2",
MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1) = " ", " ",
true, ""
)
)
在这种情况下,我将以下字符指定为有效字符:t、e、s、T、E、S、2 和空格字符。
显然,您需要将公式扩展到完整的字母表,分别列出每个大写和小写字符。同样,如果您想保留这些数字,请将其扩展为包括数字。请注意,数字被编码为字符串。
这是如何工作的:
简而言之,我们将源字符串拆分为一个单独的字符数组,然后对于每个字符,检查它是否在我们的有效字符集中,如果是则将其包含在结果中,否则将其替换为空字符串不是。
'IFS' 函数一次通过一对参数。如果第一个参数的计算结果为真,则返回第二个参数。如果不是,它将继续下一对参数 - 这就是为什么您会看到每行列出两次字母的原因。IFS 函数中的最后一对值是集合 'true' 和空字符串。这就是说,如果我们到达有效值集的末尾(即没有匹配有效值),则返回空字符串。
更多关于为什么这样做的背景:
这是ExcelJet给出的解决方案的变体。在该解决方案中,TEXTJOIN 函数(用于连接数组的值)与 INDIRECT 函数(将字符串拆分为数组)以及数学运算符(加号)一起用于强制计算每个字符之间的计算在带有数值的字符串中。字符串中的数字字符将返回数值,而其他字符将返回错误。该解决方案使用函数 ISERR 检查错误以决定是否在最终输出中包含给定字符。那里有一篇类似的文章可以反过来解决 - 排除数字并保留字母。
我想要解决的问题是让编码人员决定哪些值是有效的,哪些不是。我尝试将 VLOOKUP 和 INDEX 函数与 INDIRECT 函数合并,但它们仅适用于字符串中的第一个字符。诀窍在于,并非所有函数都会以评估数组中每个元素(即字符串中的每个字符)的方式作用于INDIRECT 的输出。秘密在于 ExcelJet 使用了数学运算符。如果您查看 Microsoft 的完整功能参考,IFS 被归类为“逻辑”功能。我怀疑逻辑函数可以以这种方式与 INDIRECT 一起使用。
(注意:我也尝试在各种组合中使用 AND 和 OR。但是,INDIRECT 计算字符串中的所有字符。例如,使用 CODE 函数获取每个字符的 ASCII 值并断言所有字符的值必须在 65 之间- 90(大写)或 97 - 122(小写字母)仅在字符串中的所有字符均为大写或全部为小写时才有效,但在混合使用时无效。)
我不知道这个解决方案的性能与之前使用 SUBSTITUTE 的建议相比如何。如果您只想去除几个字符,我建议使用 SUBSTITUTE 解决方案。如果您想明确指定要保留的有效字符(这是原始问题),请使用这个。
最后,这是您需要的确切答案,包括您在问题中没有注意到但在您的示例中显示的转换为大写。(对于不希望进行大写转换的其他人,请从此示例中删除 'UPPER' 的实例,然后以小写形式再次将字母添加到列表中,并确保将 'true'/空字符串对保留为最后一个条目在列表中。)
=TEXTJOIN("",TRUE,
IFs(
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "A", "A",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "B", "B",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "C", "C",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "D", "D",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "E", "E",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "F", "F",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "G", "G",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "H", "H",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "I", "I",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "J", "J",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "K", "K",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "L", "L",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "M", "M",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "N", "N",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "O", "O",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "P", "P",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "Q", "Q",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "R", "R",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "S", "S",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "T", "T",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "U", "U",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "V", "V",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "W", "W",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "X", "X",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "Y", "Y",
upper(MID(a1,ROW(INDIRECT(CONCATENATE("1:",LEN(a1)))),1)) = "Z", "Z",
true, ""
)
)
最初的问题是“消除除字母字符以外的所有字符” - 这个答案在不需要 VBA 的情况下可以在公式中解决问题。