这可以在Excel 2016及以上版本中用单个公式完成。
虽然pnuts的解决方案列出了要去除的显式字符,但此解决方案明确列出了有效字符。
假设您的脏数据在A列中。
假设您想要干净的数据在B列中。
在单元格B1中使用下面的最后一个公式。要将公式输入到单元格B1中,请执行以下操作:
- 点击单元格B1
- 点击公式栏
- 粘贴公式
- 按下CTRL+Shift+Enter<--重要步骤
复制单元格B1并将其向下粘贴到您需要的位置。
首先,这里有一个简短的示例来解释正在发生的事情:
=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”函数按成对出现的参数进行处理。如果第一个参数评估为true,则返回第二个参数。如果不是,则继续使用下一对参数——这就是为什么你在每行上看到字母重复两次的原因。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。