Excel宏替换部分字符串

时间:2015-07-02 03:30:22

标签: regex excel vba excel-vba replace

我在替换包含评论的数据范围内的部分字符串时遇到了问题。

如果出现ID号,我需要用X替换ID号的中间位置(例如423456789成为423xxx789)。这些ID只能以45开头,其他任何数字都应该被忽略,因为它可能是其他用途所必需的。

可悲的是,因为这些是评论,所以数据格式不一致会增加复杂程度。

代表性数据如下所示:

523 123 123
523123123
ID 545 345 345 is Mr. Jones
Primary ID 456456456 for Mrs. Brown
Mr. Smith's Id is 567567567

我需要代码只替换ID号的中间3位数字,并保留其余的单元格,以便

ID 545 345 345 is Mr. Jones 
Primary ID 456456456 for Mrs. Brown

成为(X s周围有空格或无空格

ID 545 xxx 345 is Mr. Jones 
Primary ID 456xxx456 for Mrs. Brown

我的正则表达式是找到ID成功的行,并且对没有其他文本的单元格很有效。可悲的是,对于其他单元格而言,它不会仅仅取代需要替换的3位数字,而是使单元格数据混乱。我的下面的代码适用于上面的前两个单元格,然后对其余单元格的工作效果不佳。请帮忙。

Sub FixIds()

Dim regEx As New RegExp
    Dim strPattern As String: strPattern = "([4][0-9]{2})([^a-zA-Z0-9_]?[0-9]{3})([^a-zA-Z0-9_]?[0-9]{3})|([5][0-9]{2})([^a-zA-Z0-9_]?[0-9]{3})([^a-zA-Z0-9_]?[0-9]{3})"
Dim strReplace As String: strReplace = ""
Dim strInput As String
Dim Myrange As Range
Dim NewPAN As String
Dim Aproblem As String
Dim Masked As Long
Dim Problems As Long
Dim Total As Long

'Set RegEx config/settings/properties
    With regEx
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .Pattern = strPattern ' sets the regex pattern to match the pattern above
    End With

Set Myrange = Selection

MsgBox ("The macro will now start masking IDs identified in the selected cells only.")
' Start masking the IDs
    For Each cell In Myrange
        Total = Total + 1
        ' Check that the cell is long enough to possibly be an ID and isn't already masked
        Do While Len(cell.Value) > 8 And Mid(cell.Value, 5, 1) <> "x" And cell.Value <> Aproblem
            If strPattern <> "" Then

                cell.NumberFormat = "@"
                strInput = cell.Value
                NewPAN = Left(cell.Value, 3) & "xxx" & Right(cell.Value, 3)
                strReplace = NewPAN

' Depending on the data, fix it
                If regEx.Test(strInput) Then
                    cell.Value = NewPAN
                    Masked = Masked + 1
                Else
                    ' Adds the cell value to a variable to allow the macro to move past the cell
                    Aproblem = cell.Value
                    Problems = Problems + 1
                    ' Once the macro is trusted not to loop forever, the message box can be removed
                    ' MsgBox ("Problem. Regex fail? Bad data = " & Aproblem)
                End If
            End If
        Loop
    Next cell

' All done
MsgBox ("IDs are now masked" & vbCr & vbCr & "Total cells highlighted (including blanks) = " & Total & vbCr & "Cells masked = " & Masked & vbCr & "Problem cells = " & Problems)
End Sub

1 个答案:

答案 0 :(得分:3)

我删除了Do... While循环,并更改了For Each cell In Myrange代码中的逻辑,以便逐个处理匹配项,如果我们在第一次或第四次捕获中有非空值,则创建一个特定的替换项组(我们可以选择要替换的值)。

For Each cell In Myrange
    Total = Total + 1
    ' Check that the cell is long enough to possibly be an ID and isn't already masked

        If strPattern <> "" Then

            cell.NumberFormat = "@"
            strInput = cell.Value

            ' Depending on the data, fix it
            If regEx.test(strInput) Then
              Set rMatch = regEx.Execute(strInput)
              For k = 0 To rMatch.Count - 1
                 toReplace = rMatch(k).Value
                 If Len(rMatch(k).SubMatches(0)) > 0 Then ' First pattern worked
                   strReplace = rMatch(k).SubMatches(0) & "xxx" & Trim(rMatch(k).SubMatches(2))
                 Else ' Second alternative is in place
                   strReplace = rMatch(k).SubMatches(3) & "xxx" & Trim(rMatch(k).SubMatches(5))
                 End If
                 cell.Value = Replace(strInput, toReplace, strReplace)
                 Masked = Masked + 1
               Next k
            Else
                ' Adds the cell value to a variable to allow the macro to move past the cell
                Aproblem = cell.Value
                Problems = Problems + 1
                ' Once the macro is trusted not to loop forever, the message box can be removed
                ' MsgBox ("Problem. Regex fail? Bad data = " & Aproblem)
            End If
        End If

Next cell

结果如下:

enter image description here