【问题标题】:Regular expression to match year?正则表达式匹配年份?
【发布时间】:2015-11-07 13:58:24
【问题描述】:

我是 excel vba 中正则表达式的新手,一直在查看有关堆栈溢出的一些问题,在以下链接中找到了一个很好的问题 "How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops"

这里有一些非常有用的代码,我想我可能会尝试学习和适应我的目的,我正在尝试从电子表格的单元格中匹配一个代表年份的 4 位字符串,即。 “2016 年是丰收的一年”会产生“2016”。

我从那里发布的那个问题中使用了一些稍微改动过的代码,它设法识别出一个字符串包含一年,但是我不确定如何从单元格的其余内容中分离和提取字符串,即。 2016 在相邻的单元格中独立,我应该做些什么改变?

Private Sub splitUpRegexPattern()
Dim regEx As New RegExp
Dim strPattern As String
Dim strInput As String
Dim strReplace As String
Dim Myrange As Range

Set Myrange = ActiveSheet.Range("D2:D244")

For Each c In Myrange

    strPattern = "([0-9]{4})" 'looks for (4 consecutive numbers)

    If strPattern <> "" Then
        strInput = c.Value
        strReplace = "$1"

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

        If regEx.Test(strInput) Then
            c.Offset(0, 5) = regEx.Replace(strInput, "$1") 'puts the string in an adjacent cell
        Else
            c.Offset(0, 5) = "(Not matched)"
        End If
    End If
Next
End Sub

【问题讨论】:

  • regEx.Execute() 函数返回一个匹配对象,该对象将包含许多子匹配,每个捕获组 (pattern) 在您的模式中一个。你会发现很多关于这个的描述,例如就这样。此外,将您的模式分配移出循环,它是不变的。最后,要匹配年份,您将使用 ([12][0-9]{3}) 仅匹配上一个千年和当前千年。
  • 谢谢,使用 regEx.Execute() 让它工作

标签: regex vba excel


【解决方案1】:

您可以如下显着改进您的代码:

  1. 使用变量数组而不是范围
  2. RegExp 移出循环(您为每个单元格设置相同的方式)
  3. 您的RegExp 参数可以根据您的需要减少(次要)。

    Private Sub splitUpRegexPattern()
    
        Dim regEx As Object
        Dim strPattern As String
        Dim strInput As String
        Dim X
        Dim Y
        Dim lngCnt As Long
    
        Set regEx = CreateObject("vbscript.regexp")
        X = ActiveSheet.Range("D2:D244").Value2
        Y = X
    
        strPattern = "\b[0-9]{4}\b" 'looks for (4 consecutive numbers)
    
        With regEx
            .MultiLine = True
            .Pattern = strPattern
    
            For lngCnt = 1 To UBound(X)
    
                If .Test(X(lngCnt, 1)) Then
                    Y(lngCnt, 1) = .Execute(X(lngCnt, 1))(0)
                Else
                    Y(lngCnt, 1) = "(Not matched)"
                End If
            Next
    
            Range("D2:D244").Offset(0, 5).Value2 = Y
        End With
    End Sub
    

【讨论】:

    【解决方案2】:

    user1016274,谢谢,你的评论真的很有帮助,不得不做一些搜索,但我找到了答案

    使用 regEx.Execute(strInput) 我设法返回匹配的字符串:

    Private Sub splitUpRegexPattern()
        Dim regEx As New RegExp
        Dim strPattern As String
        Dim strInput As String
        Dim strReplace As String
        Dim Myrange As Range
    
        Set Myrange = ActiveSheet.Range("D2:D244")
    
        For Each c In Myrange
    
            strPattern = "([0-9]{4})" 'looks for (4 consecutive numbers)
    
            If strPattern <> "" Then
                  strInput = c.Value
                  strReplace = "$1"
    
                With regEx
                    .Global = True
                    .MultiLine = True
                    .IgnoreCase = False
                    .Pattern = strPattern
                End With
    
                If regEx.Test(strInput) Then
                    c.Offset(0, 5) = regEx.Execute(strInput).Item(0).SubMatches.Item(0) 'this was the part I changed
                Else
                    c.Offset(0, 5) = "(Not matched)"
                End If
            End If
        Next
     End Sub
    

    【讨论】:

    • 您能否编辑您的答案并添加最终代码,以供将来研究相同问题的其他人使用?然后您可以将您的答案标记为“答案”。
    猜你喜欢
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2011-02-08
    • 2023-04-02
    • 2019-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多