Excel 如何从字符串中精确提取6个连续数字

Excel 如何从字符串中精确提取6个连续数字,excel,Excel,问题:如何从字符串中精确提取6个连续数字 例如: f657674 576767g tt454656y 465767yy x1234567 1234567x n645856g s-5656-54654657657-6576-46567785-4354 pof-user-201734545435454 4545665 345678 f546576767g rtryty 它应该给 657674 576767 454656 465767 (blank value) (blank value) 6458

问题:如何从字符串中精确提取6个连续数字

例如:

f657674
576767g
tt454656y
465767yy
x1234567
1234567x
n645856g
s-5656-54654657657-6576-46567785-4354
pof-user-201734545435454
4545665
345678
f546576767g
rtryty
它应该给

657674
576767
454656
465767
(blank value)
(blank value)
645856
(blank value)
(blank value)
(blank value)
345678
(blank value)
(blank value)
我所尝试的:(
A1
是第一个字符串的单元格)

然后我将这个公式拖动到其他行,它给出:

    657674    (right)
    576767    (right)
    454656    (right)
    465767    (right)
   (blank value)  (right) 
   (blank value)  (right)
    645856    (right)
    657457    (wrong)
    435454    (wrong)
    4545665   (wrong)  
    345678    (right)
    546576767 (wrong)
    (blank value)  (right)

版本:Excel 2016

您可能需要自定义项,而不是内置函数。这应该是可行的,但可能需要调整。OP中的示例返回的
345678
是正确的返回,但两边都没有字母。因此,我假设您想要:6个连续的数字,或者6个两边都有字母的连续数字

将其添加到工作簿模块中,您可以像
=return\u numbers(A1)
那样调用。您可能需要也可能不需要使用VBEditor

Function return_numbers(ByVal cel As Range) As String
Dim strPattern As String
Dim regEx As New RegExp

strPattern = "[a-z]\d{6}[a-z]"

With regEx
    .Global = True
    .MultiLine = True
    .IgnoreCase = True
    .Pattern = strPattern
End With

Dim matches As Object
Set matches = regEx.Execute(cel)

If Len(cel) = 6 And IsNumeric(cel) Then
    return_numbers = cel.Value
    Set regEx = Nothing
    Exit Function
End If

If matches.Count <> 0 Then
    return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 2)
ElseIf matches.Count = 0 Then
    strPattern = "[a-z]{1}\d{6}$"
    regEx.Pattern = strPattern
    Set matches = regEx.Execute(cel)
    If matches.Count <> 0 Then
        return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 1)
    ElseIf matches.Count = 0 Then
        strPattern = "^\d{6}[a-z]{1}"
        regEx.Pattern = strPattern
        Set matches = regEx.Execute(cel)
        If matches.Count <> 0 Then
            return_numbers = Mid(matches.Item(0), 1, Len(matches.Item(0)) - 1)
        End If
    End If
End If

Set regEx = Nothing

End Function
函数返回字符串形式的数字(ByVal cel作为范围)
作为字符串的Dim strPattern
Dim regEx作为新的RegExp
strPattern=“[a-z]\d{6}[a-z]”
用正则表达式
.Global=True
.MultiLine=True
.IgnoreCase=True
.Pattern=strPattern
以
暗匹配作为对象
Set matches=regEx.Execute(cel)
如果Len(cel)=6且为数字(cel),则
返回值=单元值
Set regEx=Nothing
退出功能
如果结束
如果匹配,则计数0
return_number=Mid(匹配项(0)、2、Len(匹配项(0))-2)
ElseIf匹配。然后计数=0
strPattern=“[a-z]{1}\d{6}$”
regEx.Pattern=strPattern
Set matches=regEx.Execute(cel)
如果匹配,则计数0
return_number=Mid(匹配项(0)、2、Len(匹配项(0))-1)
ElseIf匹配。然后计数=0
strPattern=“^\d{6}[a-z]{1}”
regEx.Pattern=strPattern
Set matches=regEx.Execute(cel)
如果匹配,则计数0
return_number=Mid(匹配项(0)、1、Len(匹配项(0))-1)
如果结束
如果结束
如果结束
Set regEx=Nothing
端函数

如果您想加快速度,我认为如果您切换
If/else
语句,它可能会运行得更快一些,因为如果它找到6个单独的数字,它不会总是运行正则表达式


编辑:这相当笨重。我确信有更好的正则表达式模式,所以请告诉我。

您可能需要一个UDF而不是内置函数。这应该是可行的,但可能需要调整。OP中的示例返回的
345678
是正确的返回,但两边都没有字母。因此,我假设您想要:6个连续的数字,或者6个两边都有字母的连续数字

将其添加到工作簿模块中,您可以像
=return\u numbers(A1)
那样调用。您可能需要也可能不需要使用VBEditor

Function return_numbers(ByVal cel As Range) As String
Dim strPattern As String
Dim regEx As New RegExp

strPattern = "[a-z]\d{6}[a-z]"

With regEx
    .Global = True
    .MultiLine = True
    .IgnoreCase = True
    .Pattern = strPattern
End With

Dim matches As Object
Set matches = regEx.Execute(cel)

If Len(cel) = 6 And IsNumeric(cel) Then
    return_numbers = cel.Value
    Set regEx = Nothing
    Exit Function
End If

If matches.Count <> 0 Then
    return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 2)
ElseIf matches.Count = 0 Then
    strPattern = "[a-z]{1}\d{6}$"
    regEx.Pattern = strPattern
    Set matches = regEx.Execute(cel)
    If matches.Count <> 0 Then
        return_numbers = Mid(matches.Item(0), 2, Len(matches.Item(0)) - 1)
    ElseIf matches.Count = 0 Then
        strPattern = "^\d{6}[a-z]{1}"
        regEx.Pattern = strPattern
        Set matches = regEx.Execute(cel)
        If matches.Count <> 0 Then
            return_numbers = Mid(matches.Item(0), 1, Len(matches.Item(0)) - 1)
        End If
    End If
End If

Set regEx = Nothing

End Function
函数返回字符串形式的数字(ByVal cel作为范围)
作为字符串的Dim strPattern
Dim regEx作为新的RegExp
strPattern=“[a-z]\d{6}[a-z]”
用正则表达式
.Global=True
.MultiLine=True
.IgnoreCase=True
.Pattern=strPattern
以
暗匹配作为对象
Set matches=regEx.Execute(cel)
如果Len(cel)=6且为数字(cel),则
返回值=单元值
Set regEx=Nothing
退出功能
如果结束
如果匹配,则计数0
return_number=Mid(匹配项(0)、2、Len(匹配项(0))-2)
ElseIf匹配。然后计数=0
strPattern=“[a-z]{1}\d{6}$”
regEx.Pattern=strPattern
Set matches=regEx.Execute(cel)
如果匹配,则计数0
return_number=Mid(匹配项(0)、2、Len(匹配项(0))-1)
ElseIf匹配。然后计数=0
strPattern=“^\d{6}[a-z]{1}”
regEx.Pattern=strPattern
Set matches=regEx.Execute(cel)
如果匹配,则计数0
return_number=Mid(匹配项(0)、1、Len(匹配项(0))-1)
如果结束
如果结束
如果结束
Set regEx=Nothing
端函数

如果您想加快速度,我认为如果您切换
If/else
语句,它可能会运行得更快一些,因为如果它找到6个单独的数字,它不会总是运行正则表达式


编辑:这相当笨重。我确信有更好的正则表达式模式,所以请告诉我。

灵感来源于布鲁斯,但搭配最低

Function ContainsSix(ByVal rng As Range) As String
    Dim re As RegExp
    Dim mc As MatchCollection
    Dim CellValue As Variant

    CellValue = rng.Cells(1, 1).Value2
    Set re = New RegExp
    With re
        .Pattern = "(?:\D|^)(\d{6})(?:\D|$)"
        .Global = True
        .MultiLine = True
        .IgnoreCase = True

        If .Test(CellValue) Then
            Set mc = .Execute(CellValue)
            ContainsSix = mc(0).SubMatches(0)
        End If
    End With
    Set re = Nothing
End Function
正则表达式的说明:

  • 匹配表达式,但不要捕获它。[\D| ^]
    • 从两个备选方案中进行选择
      • 不是数字的任何字符
      • 行首
  • 编号的捕获组。[\d{6}]
    • 任意数字,重复6次
  • 匹配表达式,但不要捕获它。[\D |$]
    • 从两个备选方案中进行选择
      • 不是数字的任何字符
      • 行尾

灵感来源于布鲁斯,但搭配最少

Function ContainsSix(ByVal rng As Range) As String
    Dim re As RegExp
    Dim mc As MatchCollection
    Dim CellValue As Variant

    CellValue = rng.Cells(1, 1).Value2
    Set re = New RegExp
    With re
        .Pattern = "(?:\D|^)(\d{6})(?:\D|$)"
        .Global = True
        .MultiLine = True
        .IgnoreCase = True

        If .Test(CellValue) Then
            Set mc = .Execute(CellValue)
            ContainsSix = mc(0).SubMatches(0)
        End If
    End With
    Set re = Nothing
End Function
正则表达式的说明:

  • 匹配表达式,但不要捕获它。[\D| ^]
    • 从两个备选方案中进行选择
      • 不是数字的任何字符
      • 行首
  • 编号的捕获组。[\d{6}]
    • 任意数字,重复6次
  • 匹配表达式,但不要捕获它。[\D |$]
    • 从两个备选方案中进行选择
      • 不是数字的任何字符
      • 行尾
=IFERROR(0+MID(A1,MATCH(8,MMULT)(ABS(0+MID(MID)(“ζ”&A1和“ζ”),行(索引(A:A,1):索引(A:A,LEN(A1)-5)),8),{1,2,3,4,5,6,7,8},1))-{1,0,0,0,0,0,0,0,0,1}),{1;1;1;1}),6),“

请注意,如果您没有使用英语版本的Excel,则上述部分可能需要修改

关于

=IFERROR(0+MID(A1,MATCH(8,MMULT)(ABS(ISNUMBER(0+MID(MID)(“ζ”&A1和“ζ”),行(索引(A:A,1):索引(A:A,LEN(A1)-5)),8),{1,2,3,4,5,6,7,8},1))-{1,0,0,0,0,0,0,0}),6),{code>

请注意,如果您没有使用英语版本的Excel,则上述部分可能需要ame