Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
excel函数查找单元格中字符串的模式_Excel_Vba_Find_Excel Formula_Wildcard - Fatal编程技术网

excel函数查找单元格中字符串的模式

excel函数查找单元格中字符串的模式,excel,vba,find,excel-formula,wildcard,Excel,Vba,Find,Excel Formula,Wildcard,我必须在一个牢房里找到报告中的个人ID。糟糕的是,单元格中隐藏此ID的字符串可以是任何内容,ID可以在开头、结尾、任何位置,但它就在那里。 我只知道“空格、字母、字母、数字、数字、数字、数字、数字、数字、数字、数字、空格”的模式。吉科DB544345 我正在寻找这个“面具”的正确单词,但找不到答案。谢谢你的帮助 由于评论众多,我创建了一个最简单的示例,可能代表OP正在处理的问题: A1:123456789 DB544345 asdfg asdfghjk A2:创建虚拟数据是一个DB544345难

我必须在一个牢房里找到报告中的个人ID。糟糕的是,单元格中隐藏此ID的字符串可以是任何内容,ID可以在开头、结尾、任何位置,但它就在那里。 我只知道“空格、字母、字母、数字、数字、数字、数字、数字、数字、数字、数字、空格”的模式。吉科DB544345


我正在寻找这个“面具”的正确单词,但找不到答案。谢谢你的帮助

由于评论众多,我创建了一个最简单的示例,可能代表OP正在处理的问题:

A1:
123456789 DB544345 asdfg asdfghjk

A2:
创建虚拟数据是一个DB544345难题

A3:
DB5443456和其他东西

分析了ColumnB中文本到列(以空格作为分隔符)的副本,然后应用:

=IFERROR(IF(AND(LEN(B1)=8,CODE(LEFT(B1))>64,CODE(LEFT(B1))<91,CODE(MID(B1,2,1))>64,CODE(MID(B1,2,1))<91,ISNUMBER(RIGHT(B1,6)*1),RIGHT(B1,6)*1>99999),B1,""),"")
=IFERROR(如果(和(LEN(B1)=8,代码(LEFT(B1))>64,代码(LEFT(B1))64,代码(MID(B1,2,1))99999,B1,“”)
到K1,将其复制到P1,然后K1:P1向下

对于这样的问题,一个简洁的“仅内置函数”解决方案需要稍加修改,因为由于内置Excel公式中的缺陷和怪癖,许多尝试都会死路一条或需要解决。我更喜欢单单元格公式,因为它们对一般电子表格结构的影响最小。然而,由于上面列出的限制,复杂的单单元格解决方案往往以相当长和繁琐为代价(这个答案在Excel中的公式栏上仍然只有两行)。回到你的问题,我拼凑了一个公式,可以(据我测试)用一个单细胞公式提取第一次出现的这种模式。这是一个数组公式(Ctrl+Shift+Enter而不是Enter),它假定数据在A2中。如果未找到匹配项,此粗略公式将返回前8个字符,如果字符串短于10个字符,则抛出#REF

=MID(A2,MIN(IF(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9))),1)=" ",IF(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+9,1)=" ",IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+1,1))>64,IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+1,1))<91,IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+2,1))>64,IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+2,1))<91,IF(IFERROR(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+3,6)*1>99999,FALSE),ROW(INDIRECT("A1:A"&(LEN(A2)-9)))))))))))+1,8)
让我们假设字符串长度为40个字符,并将上面的公式替换为
{1…31}
。使用此数字序列生成,我们可以检查字符1到31是否为空格:

IF(MID(A2,{1...31},1)=" "
IF(MID(A2,{1...31}+9,1)=" "
然后我们可以检查字符10到40是否为空格:

IF(MID(A2,{1...31},1)=" "
IF(MID(A2,{1...31}+9,1)=" "
然后我们可以检查字符2到32是否为大写字母:

IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+1,1))>64,
IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+1,1))<91
IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+2,1))>64,
IF(CODE(MID(A2,ROW(INDIRECT("A1:A"&(LEN(A2)-9)))+2,1))<91
如果所有条件均为TRUE,则该10位区块测试将通过原始数组的另一个实例
{1…31}
返回字符串中第一个字符的索引。否则它什么也不返回。我们获取所有返回索引的
Min
,然后使用
Mid
函数获取由上述最小索引确定的8位字符串:

=MID(A2,MIN(matching index list)+1,8)

如果我们假设开头和结尾的
空格
仅仅是为了区分ID和字符串的其余部分,我认为这是可行的;因此,如果ID位于字符串的开头或结尾,则不会出现。此公式不区分大小写。如果需要区分大小写,我们可以进行字符代码比较

=LOOKUP(2,1/((LEFT(myArr,2)>="AA")*(LEFT(myArr,2)<="ZZ")*(LEN(myArr)=8)*ISNUMBER(-RIGHT(myArr,6))),myArr)
如果最初使用B1中的光标定义myArr,如图所示参考A1,它将调整为参考名称所在单元格左侧的单元格一列


1:10
中的
10
是字符串中的最大字数,可以根据需要进行调整。

好的,我会检查,谢谢。也许我们可以通过查找所有空格来解决这个问题,查看后面的字符串是否为该长度,然后检查其格式是否正确?@pnuts我同意您的看法,VBA更适合于非黑客解决方案(因此注释upvote),但在您的第二条注释中。。。如果可以在空格之间拆分这些块,则可以使用数组公式计算8个字符的块,该数组公式基本上基于UNICODE范围转换每个字符。大写字母为2,数字为1,其他字母为0。将该数组中的每个数字提升到其在字符串中的索引的指数。总结一下。检查你的答案是否等于516。是的,我已经写了这个公式。@pnuts在公式中工作的挑战出于某种原因引起了我的兴趣。困难的部分是结合两个步骤:生成块和执行测试。在一个公式中生成一个包含所有可能块的数组并不难。在一个公式中,测试组件当然是可能的。将两者结合起来会变得古怪。@pnuts True更简单。对于这个特定的简单模式,您可以对大多数模式进行数字检查。旁注:我认为在这样的问题上说“使用代码”很容易,但我发现自己并没有在Excel中极力强调这一点,因为即使作为一名程序员,我也知道会出现的长期问题。不过,使用公式会导致对内置函数中的缺陷和怪癖进行大量破解。@pnuts看起来我的潜意识不想放弃这个问题。。。我认为如果数字部分带有破折号或包含句点,您的方法将发现错误匹配。这是一个很好的答案。它很凌乱,需要大量的空间(如果有很多空格字符),并且不是实时更新(因为缺少更好的文字),但是如果OP的主要议程是尽快提取答案,那么这就是暴力方式。取决于看不见的OP结构的结构以及他是否愿意支持它,这可能是最好的主意。对于一个不太暴力的解决方案,我已经发布了一个替代方案,它似乎可以在一个单细胞公式中完成所有这一切。你的
MID
功能不应该是
MID(B1,2,1)
而不是
MID(B1,1,1)
?@pnuts我在一台17英寸的笔记本电脑上,所以是的,屏幕很宽。当他说“空格、字母、字母、数字、数字、数字、数字、数字、数字、数字、空格”时,我就照字面意思理解了“始终有一个尾随空格。我可以通过几个方法修改它以适应ID是字符串的最后8个字符。实际上,最简单的方法是从1到n-8(而不是n-9),然后输入一个IFERROR(我当前的支票)
=TRIM(MID(SUBSTITUTE(TRIM(Sheet2!A1)," ",REPT(" ",99)),(ROW(INDIRECT("1:10"))-1)*99+1,99))