Excel Regex VBA

am46iovg  于 2023-06-07  发布在  其他
关注(0)|答案(2)|浏览(94)

我需要从Excel单元格中提取字符串的一部分,如果它匹配以下格式:“DDD/L-DDD-L/DDD-L-DD/DD”,其中D表示任何数字,L表示任何字母,大写或小写。
以下是一些例子:
细胞内容物:“BHL:200/b-003-A/094-G-08/02”
提取的字符串:“200/B-003-A/094-G-08/02”
细胞内容物:“UWI:200/c-098-C/094-G-01/00”
提取的字符串:“200/c-098-C/094-G-01/00”
细胞内容物:“总硫(质量%)= 0.013,BHL:203/a-044-C/094-G-01/00”
提取的字符串:“203/a-044-C/094-G-01/00”
注:数据格式非常不一致,因此无法选择查找“BHL”或“UWI”等关键字。
我已经做了下面的VBA函数,但它并没有像预期的那样工作

Function simpleCellRegex(Myrange As Range) As String
    Dim regEx As New RegExp
    Dim strPattern As String
    Dim strInput As String
    Dim strReplace As String
    Dim strOutput As String
    
    
    strPattern = "[0-9]{3}/[A-Za-z]-[0-9]{3}-[A-Za-z]/[0-9]{3}-[A-Za-z]-[0-9]{2}/[0-9]{2}"
    
    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""
        
        With regEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = False
            .pattern = strPattern
        End With
        
        If regEx.Test(strInput) Then
            simpleCellRegex = regEx.Replace(strInput, strReplace)
        Else
            simpleCellRegex = "Not matched"
        End If
    End If
End Function
wb1gzix0

wb1gzix01#

您应该使用regExp.Execute(strInput)(而不是Replace)并查看返回的Matches集合
这对我很有效:

Function simpleCellRegex(v) As String
    Const strPattern = "\d{3}/[A-Z]-\d{3}-[A-Z]/\d{3}-[A-Z]-\d{2}/\d{2}"
    
    Dim regEx As New RegExp, matches As Object, match As Object, sep As String
    
    With regEx
        .Global = True
        .MultiLine = True
        .IgnoreCase = True
        .Pattern = strPattern
    End With
    
    Set matches = regEx.Execute(v)
    If matches.Count > 0 Then
        For Each match In matches
            simpleCellRegex = simpleCellRegex & sep & match.Value
            sep = "; "
        Next match
    Else
        simpleCellRegex = "Not matched"
    End If
End Function
w8biq8rn

w8biq8rn2#

只是给予你一个非regex/VBA的答案;单元格内容的任何其他部分遵循这种正斜杠和连字符模式的几率有多大?换句话说,下面的工作会成功吗?

B1中的公式:

=MID(A1:A3,SEARCH("???/?-???-?/???-?-??/??",A1:A3),23)

如果这种类型的安全性还不够,您仍然可以在没有正则表达式或VBA的情况下做到这一点:

=LET(x,MID(A1,SEQUENCE(LEN(A1)),23),FILTER(x,MAP(x,LAMBDA(y,LET(z,MID(y,{1,5,7,11,13,17,19,22},{3,1,3,1,3,1,2,2}),AND(AND(ISNUMBER(--CHOOSECOLS(z,{1,3,5,7,8}))),AND(ISNUMBER(SEARCH(CHOOSECOLS(z,{2,4,6}),"abcdefghijklmnopqrstuvwxyz"))),ISNUMBER(SEARCH("???/?-???-?/???-?-??/??",y)))))),"No Matches"))

简单地说就是:

  • MID(A1,SEQUENCE(LEN(A1)),23)-从长度为23个字符的输入中获取任何可能的子字符串;
  • MID(y,{1,5,7,11,13,17,19,22},{3,1,3,1,3,1,2,2})-创建后续子字符串的数组。这将抓取所有字母数字部分;
  • AND(ISNUMBER(--CHOOSECOLS(z,{1,3,5,7,8})))-测试列出的列是否都是数字;
  • AND(ISNUMBER(SEARCH(CHOOSECOLS(z,{2,4,6}),"abcdefghijklmnopqrstuvwxyz")))-测试所有列出的列是否在字母表中找到(不区分大小写);
  • ISNUMBER(SEARCH("???/?-???-?/???-?-??/??",y))-测试所有正斜杠和连字符是否正确;
  • FILTER()现在将使用外部AND()返回所有可能的匹配(而不仅仅是一个)。

相关问题