Regex 如何使用excel正则表达式从字符串中提取广告大小

Regex 如何使用excel正则表达式从字符串中提取广告大小,regex,vba,excel,Regex,Vba,Excel,我试图从字符串中提取广告大小。广告尺寸均为标准尺寸。因此,虽然我更喜欢使用一个正则表达式来查找模式,即3个数字后跟2或3个数字,但硬编码也可以,因为我们知道大小。以下是一些广告尺寸的示例: 300x250 728x90 320x50 我能够找到一些我修改过的几乎可以工作的VBScript,但是因为我正在搜索的字符串不一致,所以在某些情况下它拉得太多了。例如: 您可以看到它如何在每个实例中都不正确匹配 我发现的VB代码实际上与所有东西都匹配,除了广告大小。我对VBScript了解不够,无法将其反

我试图从字符串中提取广告大小。广告尺寸均为标准尺寸。因此,虽然我更喜欢使用一个正则表达式来查找模式,即3个数字后跟2或3个数字,但硬编码也可以,因为我们知道大小。以下是一些广告尺寸的示例:

300x250

728x90

320x50

我能够找到一些我修改过的几乎可以工作的VBScript,但是因为我正在搜索的字符串不一致,所以在某些情况下它拉得太多了。例如:

您可以看到它如何在每个实例中都不正确匹配

我发现的VB代码实际上与所有东西都匹配,除了广告大小。我对VBScript了解不够,无法将其反转为只查找广告大小并拉取它们。因此,它会查找所有其他文本并将其删除

代码如下。有没有办法修复正则表达式,使其只返回广告大小

Function getAdSize(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 = "([^300x250|728x90])"

    If strPattern <> "" Then
        strInput = Myrange.Value
        strReplace = ""

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

        If regEx.Test(strInput) Then
            getAdSize = regEx.Replace(strInput, strReplace)
        Else
            getAdSize = "Not matched"
        End If
    End If
End Function
函数getAdSize(Myrange作为Range)作为字符串 Dim regEx作为新的RegExp 作为字符串的Dim strPattern 像弦一样的模糊的条纹 变暗字符串替换为字符串 作为字符串的暗输出 strPattern=“([^300x250 | 728x90])” 如果strPattern“”则 strInput=Myrange.Value strReplace=“” 用正则表达式 .Global=True .MultiLine=True .IgnoreCase=True .Pattern=strPattern 以 如果正则表达式测试(strInput),则 getAdSize=regEx.Replace(strInput,strReplace) 其他的 getAdSize=“不匹配” 如果结束 如果结束 端函数
请注意,数据的前面不总是下划线,有时前后都是破折号或空格。

如果始终是3个字符,然后是x,并且始终在下划线之间,则此公式可能有效-相应地进行调整

=iferror(mid(A1,search("_???x*_",A1)+1,search("_",A1,search("_???x*_",A1)+1)-(search("_???x*_",A1)+1)),"No match")

如果这个公式总是3个字符,然后是x,并且总是在下划线之间,那么这个公式可以工作-相应地调整

=iferror(mid(A1,search("_???x*_",A1)+1,search("_",A1,search("_???x*_",A1)+1)-(search("_???x*_",A1)+1)),"No match")

我已经设法得到了大约95%的所需答案-下面的正则表达式将删除
DDDxDD
大小,并返回其余的

Option Explicit

Public Function regExSampler(s As String) As String

    Dim regEx           As Object
    Dim inputMatches    As Object
    Dim regExString     As String

    Set regEx = CreateObject("VBScript.RegExp")

    With regEx
        .Pattern = "(([0-9]+)x([0-9]+))"
        .IgnoreCase = True
        .Global = True

        Set inputMatches = .Execute(s)

        If regEx.test(s) Then
            regExSampler = .Replace(s, vbNullString)
        Else
            regExSampler = s
        End If

    End With

End Function

Public Sub TestMe()

    Debug.Print regExSampler("uni3uios3_300x250_ASDF.html")
    Debug.Print regExSampler("uni3uios3_34300x25_ASDF.html")
    Debug.Print regExSampler("uni3uios3_8x4_ASDF.html")

End Sub
例如,你会得到:

uni3uios3__ASDF.html
uni3uios3__ASDF.html
uni3uios3__ASDF.html
从这里,您可以继续尝试找到反转显示的方法

编辑: 从95%到100%,条件块应更改为以下内容:

If regEx.test(s) Then
    regExSampler = InputMatches(0)
Else
    regExSampler = s
End If

我已经设法得到了大约95%的所需答案-下面的正则表达式将删除
DDDxDD
大小,并返回其余的

Option Explicit

Public Function regExSampler(s As String) As String

    Dim regEx           As Object
    Dim inputMatches    As Object
    Dim regExString     As String

    Set regEx = CreateObject("VBScript.RegExp")

    With regEx
        .Pattern = "(([0-9]+)x([0-9]+))"
        .IgnoreCase = True
        .Global = True

        Set inputMatches = .Execute(s)

        If regEx.test(s) Then
            regExSampler = .Replace(s, vbNullString)
        Else
            regExSampler = s
        End If

    End With

End Function

Public Sub TestMe()

    Debug.Print regExSampler("uni3uios3_300x250_ASDF.html")
    Debug.Print regExSampler("uni3uios3_34300x25_ASDF.html")
    Debug.Print regExSampler("uni3uios3_8x4_ASDF.html")

End Sub
例如,你会得到:

uni3uios3__ASDF.html
uni3uios3__ASDF.html
uni3uios3__ASDF.html
从这里,您可以继续尝试找到反转显示的方法

编辑: 从95%到100%,条件块应更改为以下内容:

If regEx.test(s) Then
    regExSampler = InputMatches(0)
Else
    regExSampler = s
End If

编辑:因为它实际上不是下划线分隔的,所以我们不能使用
拆分
。但是,我们可以迭代字符串并手动提取“#x#”。我已经更新了代码以反映这一点,并验证了它的工作是否成功

Public Function ExtractAdSize(ByVal arg_Text As String) As String

    Dim i As Long
    Dim Temp As String
    Dim Ad As String

    If arg_Text Like "*#x#*" Then
        For i = 1 To Len(arg_Text) + 1
            Temp = Mid(arg_Text & " ", i, 1)
            If IsNumeric(Temp) Then
                Ad = Ad & Temp
            Else
                If Temp = "x" Then
                    Ad = Ad & Temp
                Else
                    If Ad Like "*#x#*" Then
                        ExtractAdSize = Ad
                        Exit Function
                    Else
                        Ad = vbNullString
                    End If
                End If
            End If
        Next i
    End If

End Function
使用Select Case布尔逻辑而不是嵌套If语句的同一函数的替代版本:

Public Function ExtractAdSize(ByVal arg_Text As String) As String

    Dim i As Long
    Dim Temp As String
    Dim Ad As String

    If arg_Text Like "*#x#*" Then
        For i = 1 To Len(arg_Text) + 1
            Temp = Mid(arg_Text & " ", i, 1)

            Select Case Abs(IsNumeric(Temp)) + Abs((Temp = "x")) * 2 + Abs((Ad Like "*#x#*")) * 4
                Case 0: Ad = vbNullString       'Temp is not a number, not an "x", and Ad is not valid
                Case 1, 2, 5: Ad = Ad & Temp    'Temp is a number or an "x"
                Case 4, 6: ExtractAdSize = Ad   'Temp is not a number, Ad is valid
                           Exit Function
            End Select
        Next i
    End If

End Function

编辑:因为它实际上不是下划线分隔的,所以我们不能使用
拆分
。但是,我们可以迭代字符串并手动提取“#x#”。我已经更新了代码以反映这一点,并验证了它的工作是否成功

Public Function ExtractAdSize(ByVal arg_Text As String) As String

    Dim i As Long
    Dim Temp As String
    Dim Ad As String

    If arg_Text Like "*#x#*" Then
        For i = 1 To Len(arg_Text) + 1
            Temp = Mid(arg_Text & " ", i, 1)
            If IsNumeric(Temp) Then
                Ad = Ad & Temp
            Else
                If Temp = "x" Then
                    Ad = Ad & Temp
                Else
                    If Ad Like "*#x#*" Then
                        ExtractAdSize = Ad
                        Exit Function
                    Else
                        Ad = vbNullString
                    End If
                End If
            End If
        Next i
    End If

End Function
使用Select Case布尔逻辑而不是嵌套If语句的同一函数的替代版本:

Public Function ExtractAdSize(ByVal arg_Text As String) As String

    Dim i As Long
    Dim Temp As String
    Dim Ad As String

    If arg_Text Like "*#x#*" Then
        For i = 1 To Len(arg_Text) + 1
            Temp = Mid(arg_Text & " ", i, 1)

            Select Case Abs(IsNumeric(Temp)) + Abs((Temp = "x")) * 2 + Abs((Ad Like "*#x#*")) * 4
                Case 0: Ad = vbNullString       'Temp is not a number, not an "x", and Ad is not valid
                Case 1, 2, 5: Ad = Ad & Temp    'Temp is a number or an "x"
                Case 4, 6: ExtractAdSize = Ad   'Temp is not a number, Ad is valid
                           Exit Function
            End Select
        Next i
    End If

End Function


如果我能让正则表达式完全按照模式而不是相反的模式来拉,这将非常有用。@garek007-尝试了大约10分钟,没有成功。明天会再试一次,但希望有人能在之前做到。如果有人想办法,请随意编辑这篇文章。我会感谢你的。如果我能想出如何使用正则表达式来提取模式,这将是一个完美的选择,您可以将
regExSampler=.Replace(s,vbNullString)
更改为一个未使用的字符,如波浪线。然后,您只需计算波浪线前后的字符数,然后执行
MID
。这并不优雅,但很好。@FernandoJ.Rivera-看看这里,问题的两个答案-如果我能让正则表达式完全按照模式而不是相反的模式来拉,这将非常有用。@garek007-尝试了大约10分钟,但没有成功。明天会再试一次,但希望有人能在之前做到。如果有人想办法,请随意编辑这篇文章。我会感谢你的。如果我能想出如何使用正则表达式来提取模式,这将是一个完美的选择,您可以将
regExSampler=.Replace(s,vbNullString)
更改为一个未使用的字符,如波浪线。然后,您只需计算波浪线前后的字符数,然后执行
MID
。这并不优雅,但很好。@FernandoJ.Rivera-看看这里,这个问题的两个答案-不幸的是,它并不总是一样的,这就是为什么这么困难的原因。你可以更新你的答案,我会标记它。你更需要信用卡,对吗?不幸的是,它并不总是一样的,这就是为什么这么困难的原因。你可以更新你的答案,我会标记它。您更需要cred,对吗?在您提供的示例数据中,广告大小似乎总是被下划线(
\uu
)包围。总是这样吗?如果是这样的话,这将非常简单。不总是,有时在您提供的示例数据中,它是一个破折号或空格,看起来广告大小总是被下划线(
\uu
)包围。总是这样吗?如果是这样的话,这就很容易了。不,不总是这样,有时是破折号或空格。对不起,不是。我已经更新了我的问题,以注意到。选择逻辑是如此的性感,我希望我能投票两次。好的,我将把这个标记为正确的,因为它是最全合一的解决方案。我如何修改此选项以查找/12345/之间的数字