Microsoft Word 2010 VBA: Using regex to find and replace -


i'm trying allow our staff mask middle 8 digits of credit card data in old documents. figure macro using regex find , replace fastest way them. masking pci dss requirement, , there may hundreds or thousands of documents mask data in.

i've had luck below code, identify , modify strings beyond 16 characters standard credit card , i'm not sure how stop false-positives. solved nhahtdh

the following identifies visa, mastercard , amex cards, above mentioned issue. improved adding regex more card types, , adding common characters used break long number.

the below code works, improved. can improve by:

  • include luhn algorithm checking
  • include additional common number separators (what else commonly used?)
  • include other popular card brands
  • stop find , replace false-positives (e.g. 44445555666677778 should excluded). solved nhahtdh
    sub pci_mask_card_numbers() ' ' macro search document numbers visa, mastercard , amex credit card pans , mask them xs '    dim counter long    dim preexisting long  ' let user know what's happen     dim msg, style, title, response, mystring     msg = "the macro attempt mask credit card numbers can identify.  e.g. 4444555566667777 become 4444xxxxxxxx7777"     style = vbinformation     title = "pci dss - credit card masking"     response = msgbox(msg, style, title)  ' count how many things masked pans final tally correct     selection.homekey unit:=wdstory     activedocument.content.find         while .execute(findtext:="xxxx", forward:=true, format:=true, _            matchwholeword:=true) = true            preexisting = preexisting + 1         loop     end     preexisting = preexisting / 2   ' because masks break counted twice     selection.homekey unit:=wdstory     activedocument.content.find         while .execute(findtext:="xxxxxxxx", forward:=true, format:=true, _            matchwholeword:=false) = true            preexisting = preexisting + 1         loop     end  ' ########  start masking pans  ###################################################  ' mastercard - 16 digits straight     selection.homekey unit:=wdstory     selection.find.clearformatting     selection.find.replacement.clearformatting     selection.find         .text = "<([4][0-9]{3})([0-9]{4})([0-9]{4})([0-9]{4})>"         .replacement.text = "\1xxxxxxxx\4"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' visa - 16 digits straight     selection.find         .text = "<([5][0-9]{3})([0-9]{4})([0-9]{4})([0-9]{4})>"         .replacement.text = "\1xxxxxxxx\4"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' amex - 15 digits straight     selection.find         .text = "<([3][0-9]{2})([0-9]{4})([0-9]{4})([0-9]{4})>"         .replacement.text = "\1xxxxxxxx\4"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' visa , mastercard - pan broken :     selection.find         .text = "<([4][0-9]{3})(:[0-9]{4}:[0-9]{4}:)([0-9]{4})>"         .replacement.text = "\1:xxxx:xxxx:\3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall     selection.find         .text = "<([5][0-9]{3})(:[0-9]{4}:[0-9]{4}:)([0-9]{4})>"         .replacement.text = "\1:xxxx:xxxx:\3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' visa , mastercard - pan broken .     selection.find         .text = "<([5][0-9]{3})(.[0-9]{4}.[0-9]{4}.)([0-9]{4})>"         .replacement.text = "\1.xxxx.xxxx.\3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall     selection.find         .text = "<([4][0-9]{3})(.[0-9]{4}.[0-9]{4}.)([0-9]{4})>"         .replacement.text = "\1.xxxx.xxxx.\3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' visa , mastercard - pan broken spaces     selection.find         .text = "<([4][0-9]{3})( [0-9]{4} [0-9]{4} )([0-9]{4})>"         .replacement.text = "\1 xxxx xxxx \3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall     selection.find         .text = "<([5][0-9]{3})( [0-9]{4} [0-9]{4} )([0-9]{4})>"         .replacement.text = "\1 xxxx xxxx \3"         .forward = true         .wrap = wdfindcontinue         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall  ' visa , mastercard - pan broken -     selection.find         .text = "<([5][0-9]{3})(-[0-9]{4}-[0-9]{4}-)([0-9]{4})>"         .replacement.text = "\1-xxxx-xxxx-\3"         .forward = true         .wrap = wdfindask         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall     selection.find         .text = "<([4][0-9]{3})(-[0-9]{4}-[0-9]{4}-)([0-9]{4})>"         .replacement.text = "\1-xxxx-xxxx-\3"         .forward = true         .wrap = wdfindask         .format = false         .matchcase = false         .matchwholeword = false         .matchallwordforms = false         .matchsoundslike = false         .matchwildcards = true     end     selection.find.execute replace:=wdreplaceall     selection.homekey unit:=wdstory  ' ########  done masking pans  ###################################################  ' count how many changes done     selection.homekey unit:=wdstory     activedocument.content.find         while .execute(findtext:="xxxx", forward:=true, format:=true, _            matchwholeword:=true) = true            counter = counter + 1         loop     end     counter = counter / 2   ' because masks break counted twice     selection.homekey unit:=wdstory     activedocument.content.find         while .execute(findtext:="xxxxxxxx", forward:=true, format:=true, _            matchwholeword:=false) = true            counter = counter + 1         loop     end     counter = counter – preexisting   ' new masks less previous mask-like data  ' let user know job done     msg = "the macro has masked " & str$(counter) & " credit cards. check results , save file if changes correct. if there issues masking changes, not save file , consult team."     style = vbinformation     title = "pci dss - credit card masking." & str$(counter) & " cards masked"     response = msgbox(msg, style, title) end sub 

since seems using word wildcard syntax, can use <, asserts beginning of word, , >, asserts end of word prevent pattern matching when text preceded or succeeded letters or numbers (which how seems work simple testing).

using

"([4][0-9]{3})(-[0-9]{4}-[0-9]{4}-)([0-9]{4})" 

as example, modify into

"<([4][0-9]{3})(-[0-9]{4}-[0-9]{4}-)([0-9]{4})>" 

Comments

Popular posts from this blog

Magento/PHP - Get phones on all members in a customer group -

php - Bypass Geo Redirect for specific directories -

php - .htaccess mod_rewrite for dynamic url which has domain names -