【问题标题】:How to extract specific numbers from a text string in Excel?如何从 Excel 中的文本字符串中提取特定数字?
【发布时间】:2021-02-26 14:09:02
【问题描述】:

我有一个看起来像这样的数据集

abcdefg-1004958-2019-服务

xyz-3104568-technology ltd-UG32594

xxfgdrtg-GH267384-FO(1082564)-2016-软件

FO501117898-ahdndje-2016-服务

我需要从这个数据集中提取 1004958、3104568、1082564、501117898。换句话说,任何大于 100000 的都必须返回。

有什么公式可以做到这一点吗?因为我有10000多个这样的条目,它们的顺序不均匀,我也不能使用文本到列。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 我认为正则表达式是解决这个问题的更好方法。正则表达式可能非常强大,但它的缺点是它可能会变得(处理器)耗时。在您的情况下,正则表达式非常简单:\d{6,} 这意味着“在一行中找到 6 个或更多数字的字符串中的任何部分”。 Here 解释了如何在 excel 中使用正则表达式,但还有许多其他工具可以为您完成此正则表达式任务。

标签: excel text excel-formula numbers office365


【解决方案1】:

使用 Microsoft365,您可以尝试:

B1中的公式:

=MAX(FILTERXML("<t><s>"&CONCAT(IFERROR(MID(A1,SEQUENCE(LEN(A1)),1)*1,"</s><s>"))&"</s></t>","//s[.*0=0]"))

【讨论】:

  • 非常酷的把戏 JvDV。挖帖子debugcn.com/en/article/21139068.html
  • @Chris,谢谢。似乎某物/某人从 SO 中复制了它。 =)
  • @JvdV - 哈哈。刚刚花了过去的时间将所有这些用例放入工作簿中。太有帮助了!!不过注意到了一些小的修改。我认为 '//s[count(node())=0]' 应该是 '//s[count(node())=1]', '//s[contains(concat(., before::* [2]), 'FA')]' 没有根据示例字符串产生任何结果,并且 '//s[not(node())]' 给我一个值错误。不确定这是他们的复制和粘贴错误,还是您原始帖子中的错误。想我会提到它不管:)
  • @Chris,看起来很疯狂://s[count(node())=0] 是正确的语法。让我们想象一下"ABC|123|DEF||456|XY-1A|ZY-2F|XY-3F||XY-4f|xyz|123",您会看到它会为两个空节点返回两个错误值。 //s[not(node())] 相当于另一个。两者都意味着返回空节点。 Excel 不会真正将这些处理为空字符串值,而是不幸地返回(多个)错误。此外,//s[contains(concat(., preceding::*[2]), 'FA')] 是正确的语法,并且在尝试返回 "DEF" 时,它应该返回给我。不确定您是否在某处犯了一个小错字?
  • @Chris,请注意,您找到并分享的链接确实错过了我最近添加的一些关于转义某些字符的信息。请参阅here 的完整答案。感谢您在FILTERXML() 分享共同的兴趣 =)
【解决方案2】:

您可以使用用户定义的函数。这是我想出的:

Function FunNumber(RngTarget As Range, Optional BlnReportAsNumber As Boolean = True, Optional BytPlacement As Byte = 1)
    
    'Declarations.
    Dim StrValue As String
    Dim BytPosition As Byte
    Dim StrString01 As String
    
    'Setting.
    StrValue = RngTarget.Cells(1, 1).Value
    
    'Covering each character in StrValue.
    For BytPosition = 1 To Len(StrValue)
        'Removing any non-numerica character from StrValue.
        If Not IsNumeric(Mid(StrValue, BytPosition, 1)) Then
            StrValue = Left(StrValue, BytPosition - 1) & " " & Right(StrValue, Len(StrValue) - BytPosition)
        End If
    Next
    
    'Removing leading and trailing spaces from StrValue.
    StrValue = Trim(StrValue)
    
    'Covering each character in StrValue but the last one.
    For BytPosition = 1 To Len(StrValue) - 1
        'Removing any multiple space.
        If Mid(StrValue, BytPosition, 2) = "  " Then
            StrValue = Left(StrValue, BytPosition - 1) & " " & Right(StrValue, Len(StrValue) - BytPosition - 1)
            BytPosition = BytPosition - 1
        End If
    Next
    
    'Setting FunNumber.
    FunNumber = ""
    
CP_Small_Number_Removed:

    'Covering each section of StrValue marked by a space.
    For BytPosition = 0 To UBound(Split(StrValue, " "))
        
        'Setting StrString01 as section of StrValue marked by space.
        StrString01 = Split(StrValue, " ")(BytPosition)
        
        'Checking for a number smaller than 100000.
        If Len(StrString01) < 6 Then
            
            'Removing the number smaller than 100000.
            Select Case BytPosition
                Case Is = 0
                    StrValue = Right(StrValue, Len(StrValue) - Len(StrString01) - 1)
                    GoTo CP_Small_Number_Removed
                Case Is < UBound(Split(StrValue, " "))
                    StrValue = Replace(StrValue, " " & StrString01 & " ", " ")
                    GoTo CP_Small_Number_Removed
                Case Is = UBound(Split(StrValue, " "))
                    StrValue = Left(StrValue, Len(StrValue) - Len(StrString01) - 1)
                    GoTo CP_Small_Number_Removed
            End Select
            
        End If
    Next
    
    
    'Setting FunNumber.
    FunNumber = Split(StrValue, " ")(BytPlacement - 1)
    
    'Resetting FunNumber as number if needed.
    If BlnReportAsNumber = True Then
        FunNumber = FunNumber * 1
    End If
    
End Function

把它放在一个模块中。假设您的字符串在单元格 A1 中。在另一个单元格中写入=FunNumber(A1),您应该会获得所需的结果。如果您希望将其报告为文本(可能前导零很重要),您可以写=FunNumber(A1,FALSE)。如果有多个大于 100000 的数字,并且您想查找例如第二个,请编写类似 =FunNumber(A1,,2) 的内容(您当然可以指定您想要一个字符串还是一个数字,同时也指定您想要第二个或第三个或任何数字)。如果找不到大于 100000 的数字,则该函数返回 #VALUE 错误。

【讨论】:

    【解决方案3】:

    对于那些可以使用 LibreOffice Calc 的人来说,答案要简单得多,因为 Calc 默认支持正则表达式:

    =REGEX(A1;"\d{6,}")
    

    问题是关于 Excel,但由于答案的复杂性差异如此巨大,我不想隐瞒 LibreOffice 的答案。

    【讨论】:

    • 更改为 \d{7,} 以获得正确的结果。
    • @JvdV "Baie dankie" 供您评论。我知道计算这么多的零很困难,但提问者问“任何大于 100000 的都必须返回”。恕我直言,这意味着 \d{6,},尽管有一个问题:这个正则表达式 大于或等于 100,000。如果必须排除 100,000,则答案要复杂得多。但是接受的答案也包括100,000,所以我认为这不是问题。
    • 我理解您的意思,但您当前的解决方案在第三个样本上产生了错误的结果。这只是一个提示
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多