【问题标题】:Extract nth Occurance Number from String从字符串中提取第 n 个出现次数
【发布时间】:2016-06-09 09:17:40
【问题描述】:

我有一列包含文本字符串的单元格,其中包括文本和数字。我找到了一个很棒的公式,可以找到字符串中的第一个数字并将其提取到相应的单元格中,例如

文本字符串:“初始佣金为 9,999.99 英镑,然后从第 99 个月起续订佣金为 9.9 英镑”

在单元格旁边输入此公式=LOOKUP(99^99,--("0"&MID(F8,MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},F8&"0123456789")),ROW($1:$10000)))) 将提取第一个数字 9,999.99。

这不是我的公式,而是我发现并喜欢的公式,但希望能够表明我还想提取第二个出现的数字和第三个出现的数字。基本上将字符串中的所有数字,放入单独的单元格中。

你们中是否有聪明人能够建议对公式进行修改以允许这样做?

提前致谢。

【问题讨论】:

  • 如果您的原始文本在 A1 中,并且第一个删除的数字显示在 B1 中。在 C1 中,您可以使用 SUBSTITUTE 函数并将“”替换为 A1 文本,只要找到 B1 中的值。然后在 D1 中,重复您的公式以提取第一个数字,但这次您从中提取的文本位于 C1 中。重复这个过程,然后你就可以在自己的单元格中找到所有的数字。
  • 谢谢你,这是我想到的一个选项,但试图避免额外的列以使其工作,因为它将成为最终导入访问数据库的自动化过程的一部分。
  • 您总是可以在不用作选项的区域中向右折腾一些中间列。设置公式后,您应该能够移动它们。当您完成重新排列列时,只有数字列会并排。
  • 你知道一个句子中最多可以出现多少个数字吗?这可能更适合 VBA 进行提取。
  • 最多3个数字

标签: string excel excel-formula


【解决方案1】:

所以这是建议的功能 - 它使用简单的 2 状态方法。一般解决方案的问题是使用逗号作为千位分隔符和问题中的部分文本。所以 999,999 可以是一个数字或两个单独的数字。此外,99,99,99 虽然不是有效数字,但从 ISNUMERIC 返回 TRUE,从 VAL 返回 99。您可以尝试找到可能的最长数字,但如果遇到诸如 99,999,99 之类的字符串,您将不得不回溯,而简单的 2 状态模型将无法工作。

所以我认为这种简单级别的唯一实用解决方案是使用参数调用函数,该参数告诉它(a)将逗号视为千位分隔符(并且基本上忽略它)或(b ) 将其视为分隔符,因此在遇到逗号时停止向数字添加字符。

如果需要,它应该很容易处理初始减号,但目前版本还没有。

Function GetNthNumber(s As String, n As Integer, Optional CommaAsThousands As Boolean = True) As Variant

Dim c, testNumber, number As String

' Ignore commas if treated as thousands separator
If CommaAsThousands Then s = Replace(s, ",", "")

s = s & "x"

Dim i, j, count As Integer

Dim inNumber As Boolean

inNumber = False

' Loop through each character of string

For i = 1 To Len(s)

c = Mid(s, i, 1)

' Part of a number - append new character or finish number

    If inNumber Then
        If IsNumeric(number & c) And (CommaAsThousands Or c <> ",") Then
            number = number & c
        Else
            inNumber = False
            If count = n Then Exit For
        End If
    Else

' Not part of a number - start new number or do nothing

        If IsNumeric(c) Then
            inNumber = True
            number = c
            count = count + 1
        End If

    End If
Next i

'Return nth number or #Value error

If count = n Then
    GetNthNumber = Val(number)
Else
    GetNthNumber = CVErr(xlErrValue)
End If
End Function

以下是以两种不同方式调用时的结果(第一行以逗号作为千位分隔符,第二行以逗号作为分隔符):-

【讨论】:

  • 谢谢@tom-sharpe 我今天会尝试玩它,但可能要等到下周。
【解决方案2】:

好吧,我最终用一个疯狂的长公式解决了这个问题。 它不是最漂亮的公式,但它确实有效。

感谢您的建议,这些建议确实引导我找到答案。这是我的公式。

文本字符串位于名为“事件标签”公式参考 [@[事件标签]] 的表格列中。

所以对于第一个数字,我使用这个公式:

=SUBSTITUTE(LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),LOOKUP(99^99,--("0"&MID(LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1)),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},LEFT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])+1))&"0123456789")),ROW($1:$10000)))))

对于第二个数字,我使用以下公式:

=SUBSTITUTE(RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),LOOKUP(99^99,--("0"&MID(RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]]))),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},RIGHT([@[Event Label]],FIND("Â",[@[Event Label]],FIND("Â",[@[Event Label]])))&"0123456789")),ROW($1:$10000)))))

对于最后的第三个数字,我使用以下公式:

=SUBSTITUTE(RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),LOOKUP(99^99,--("0"&MID(RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1),MIN(SEARCH({0,1,2,3,4,5,6,7,8,9},RIGHT([@[Event Label]],LEN([@[Event Label]])-FIND("month",[@[Event Label]])+1)&"0123456789")),ROW($1:$10000)))))

这对我有用,因为我已经定义了在文本字符串中始终位于相同位置的文本字符串。

我确信可能有更好的方法,但现在可以了。

【讨论】:

    猜你喜欢
    • 2016-07-25
    • 1970-01-01
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多