根据条件从字符串中提取一个数字

Wal*_*eed 1 regex excel vba extract

下面的代码从字符串中提取所有数字,甚至将它们组合起来。
但我只需要按照规则提取一个整数:
1-该数字是一位两位数字(加上小数部分,如果存在)。
2-如果数字后跟"orinchin,则提取它并忽略字符串中的其余数字。
3-如果未找到上述条件(2),则提取第一个数字并忽略字符串中的其余数字。

当前字符串 预期结果
INSPECT-8''水12管 8
检查 - 8.5" 水 12 8.5
检查 - 4 水 5.5" 5.5
PM- 6.5 英寸 H44 起 6.5
PM-36英寸管道M1T 36
M2T 的 PM-36 管道 36
PM-18"*12" 管道来自 M1T 18
PM-36 5" M1T 起 5
PM-123 MT 管道
Public Function GetNumeric(CellRef As String)
    Dim StringLength As Long, i As Long, Result As Variant
    StringLength = Len(CellRef)
    For i = 1 To StringLength
      If IsNumeric(Mid(CellRef, i, 1)) Then
         Result = Result & Mid(CellRef, i, 1)
      End If
    Next i
    GetNumeric = Result
End Function
Run Code Online (Sandbox Code Playgroud)

Jvd*_*vdV 6

也许可以使用正则表达式创建您自己的 UDF。也许是这样的:

Public Function RegexExtract(str, pat, Optional gFlag As Boolean = False, Optional pos As Integer = 0, Optional cse as Boolean = True) As String

Static RE As Object: If RE Is Nothing Then Set RE = CreateObject("vbscript.regexp")

RE.Pattern = pat
RE.Global = gFlag
RE.IgnoreCase = cse

If RE.Test(str) Then
    RegexExtract = RE.Execute(str)(pos)
Else
    RegexExtract = vbNullString
End If

End Function
Run Code Online (Sandbox Code Playgroud)

请注意,我创建了一个默认为 false 的可选全局标志,它应该只拉出单元格中的第一个命中。可选的 pos 变量用于返回某个匹配项,以防您希望在将全局标志设置为 true 时以某种方式返回其他数字。另请注意,默认情况下使用设置为 true 的大小写标志来匹配不区分大小写。

您可以像这样调用上面的内容:

=IFERROR(--RegexExtract(A1,"\b\d\d?(?!\d)(?=\s*(?:""|''|in(?:ch)?\b)?)"),"")
Run Code Online (Sandbox Code Playgroud)

使用的模式代表:

  • \b\d\d?- 具有 1 位数字和第二个可选数字的字边界;
  • (?!\d)- 负向前瞻断言不再有数字;
  • (?=\s*(?:"|''|in(?:ch)?\b)?)- 断言位置的正向前瞻后面跟着 0+(贪婪)空白字符,并且:
    • "- 双引号,或者;
    • ''- 两个单引号,或者;
    • in(?:ch)?\b- 从字面上看,“in”后跟可选的“ch”和单词边界,以确认字母不是较大子字符串的一部分,以防止误报。

编辑1

根据下面OP的评论;在某些情况下,可能有多个兴趣不在第一位置。由于 OP 也允许匹配没有英寸的数字,因此这里的添加是包含一个负前瞻,它将断言有效模式没有第二次出现:

\b\d\d?(?!\d|.*\b\d+\s*(?:""|''|in(?:ch)?\b))(?=\s*(?:""|''|in(?:ch)?\b)?)
Run Code Online (Sandbox Code Playgroud)

我认为这与以下内容隐式相同:

\b\d\d?(?!\d|.*\b\d+\s*(?:""|''|in(?:ch)?\b))
Run Code Online (Sandbox Code Playgroud)

编辑2

为了允许小数,您可以包含一个可选的非捕获组:

=IFERROR(--RegexExtract(A2,"\b\d\d?(?:\.\d+)?(?!\d|.*\b\d+\s*(?:""|''|in(?:ch)?\b))"),"")
Run Code Online (Sandbox Code Playgroud)