Michael Bahr
jedi at charm.net
Sat Apr 19 17:48:44 CDT 2008
Hi Mark, here is an improved function to capture cc numbers within a string. The other one I sent you only worked 2/3, the contiguous part failed by not capturing enough. However this version fixes that. I have included instructions within the function so please follow them. Also keep this function handy somewhere and use it as a template for future regular expressions. Explanation: This function only demonstrates the power of regular expressions and includes a built-in test string. All you need to do is copy it and paste into a module and run it. I modified the test pattern to ccpattern = "(\d{3,5}((\ |-|\.)\d{3,5})+|\d{13,16})" and is in 2 parts. Part 1, \d{4,6}((\ |-|\.)\d{4,6})+ includes some enhancements. The \d{4,6} means that I am looking for either 4,5,6 digits-no more, no less. I removed the ? from the (\ |-|\.) because now I want to implicitly look for groups of ((\ |-|\.)\d{4,6})+ like .12345. So now I will capture numbers like 1234-567899-90001 and 1234 0001.1000-9999 and so on. Btw, you always modify the (\ |-|\.) to suit your needs adding more simply by inserting a | between each char. Notice that some chars have a \ in front-that just means to use the literal char as some of these chars have special meanings. Part 2, |\d{13,16} is new in that this is an OR condition that uses the "|" pipe or vertical bar as the OR part. So now I am implicitly looking for 13,14,15,16 contiguous digits. When you ready to implement this into your project copy the guts into your code. Enjoy, Mike... ' ' set a debug breakpoint at the regex.test(str) and ' step 1 line at time ' ' in the debug window add watches for the following: ' matches ' matches(0).submatches ' matches(1).submatches ' matches(2).submatches ' matches(3).submatches ' matches(4).submatches ' ccnumber ' ' these will contain the cc number if matched ' Function ccMatch() As Boolean Dim regex As Object Dim ccpattern As Variant Dim regexMatch As Boolean Dim str As String Dim matches As Variant str = "The quick brown fox with cc numbers 1234 0001.1000-9999, 1234-567899-90001, 123.100000-99999, 1234567890123, and 0000999910009999 jumped over the fence" ccMatch = 0 ccpattern = "(\d{4,6}((\ |-|\.)\d{4,6})+|\d{13,16})" ' ccpattern = "(\d+((\ |-|\.)?\d+)+)" Set regex = CreateObject("VBScript.RegExp") ' global is needed for multiple matches otherwise ' will stop after first match regex.Global = True ' regexMatch = True ' regex.ignorecase = True ' test for cc number regex.pattern = ccpattern regexMatch = regex.test(str) Set matches = regex.Execute(str) ' stop stepping here and look at the results If (regexMatch) Then ' got a match ' the matches collection show how many matches there are in the string ' the submatches index is the parenthesis order starting ' from left to right, in debug these are shown as item 1, item 2, etc ' and tell you how to numerate the collection starting with 0 ' iterate through collection For Each thisitem In matches ccnumber = thisitem ' now you can use your best method for replacing the cc number ' with your string ' regex.replace Next ccMatch = 1 End If End Function *********** REPLY SEPARATOR *********** On 4/18/2008 at 8:41 PM Michael Bahr wrote: >Ok here is a function that may work for you. I have not tested it. I >leave the replace part to you. Use the debugger amply. > >' This will match the following cc numbers: >'0000-0000-0000-0000 >'0000 0000 0000 0000 >'0000000000000000 > >' >' set a debug breakpoint at the top of this function and >' step 1 line at time >' >Function ccMatch (str as String) As Boolean > Dim regex As Object > Dim ccpattern as Variant > Dim regexMatch As Boolean > Dim matches As MatchCollection > > ccMatch = 0 > ccpattern = "(\d+((\ |-)?\d+)+)" > > Set regex = CreateObject("VBScript.RegExp") > regexMatch = True > regex.Global = True > regex.ignorecase = True > > ' test for cc number > regex.pattern = ccpattern > regexMatch = regex.test(str) > > If (regexMatch) Then > ' got a match now substitute your string > ' matches(0).submatches(0) should contain the cc number > > Set matches = regex.Execute(str) > > ' once you step here look at the properties for the matches object > ' > ' the submatches index is the parenthesis order starting > ' from left to right--can be viewed in the debug window > ' while manually stepping > ccnumber = matches(0).submatches(0) > > ' now you can use your best method for replacing the cc number > ' with your string > ' regex.replace > > ccMatch = 1 > End If > >End Function > >hth. Gotta go, Dr. Who is on and then BSG. SciFi Friday. > >Mike... > > >*********** REPLY SEPARATOR *********** > >On 4/18/2008 at 6:12 PM Mark A Matte wrote: > >>Thanks Mike, >> >>I had already considered the different lengths and seperators... this >>,"(\d+((\ |-)?\d+)+)", intrigues me...what do I do with it/how do i call >>it??? The numbers I'm looking for are in the middle of the text of a MEMO >>field. >> >>Thanks again, >> >>Mark A. Matte >> >> >>> Date: Fri, 18 Apr 2008 12:32:17 -0400 >>> From: jedi at charm.net >>> To: accessd at databaseadvisors.com >>> Subject: Re: [AccessD] Search for credit card numbers >>> >>> Hi Mark, your best solution is to use a regular expression to match a >>> pattern of numbers. CC numbers can have dashes or spaces separating the >>> number groups or can be contiguous--just depends on how it was written. >>> For example using a pattern like >>> >>> (\d+((\ |-)?\d+)+) >>> >>> Meaning: >>> 1. The first set of parens (outer) capture the whole matching CC number. >>> 2. The first \d+ means one or more digits >>> 3. The ((\ |-)?\d+) means the next char either a space or "-" may exist >>> (because of the ?) and then again 1 or more digits >>> 4. And the final + is one or more of the pattern in #3. >>> >>> would cover 3 possible patterns >>> 0000-0000-0000-0000 >>> 0000 0000 0000 0000 >>> 0000000000000000 >>> >>> CC number length range from 13 to 16 digits so this should catch them. >>> however this is not foolproof. If you happen to have some other number >>> that matches that pattern then it too will get caught. >>> >>> If you want to determine the issuer then a simple case statement >matching >>> the identifier will suffice. >>> >>> Give this some thought. >>> >>> Mike... >>> >>> >>>> >>>> Hello All, >>>> >>>> I'm getting ready to build something that searches MEMO and text fields >>>> for credit card numbers (card number NOT known)...and then replace >them. >>>> >>>> Before I got started, I was wondering if anyone has any advice...or has >>>> done somthing similar. >>>> >>>> Thanks, >>>> >>>> Mark A. Matte >>>> _________________________________________________________________ >>>> Use video conversation to talk face-to-face with Windows Live >Messenger. >>>> >>http://www.windowslive.com/messenger/connect_your_way.html?ocid=TXT_TAGL M >_WL_Refresh_messenger_video_042008 >>>> -- >>>> AccessD mailing list >>>> AccessD at databaseadvisors.com >>>> http://databaseadvisors.com/mailman/listinfo/accessd >>>> Website: http://www.databaseadvisors.com >>>> >>> >>> >>> -- >>> AccessD mailing list >>> AccessD at databaseadvisors.com >>> http://databaseadvisors.com/mailman/listinfo/accessd >>> Website: http://www.databaseadvisors.com >> >>_________________________________________________________________ >>Pack up or back upuse SkyDrive to transfer files or keep extra copies. >>Learn how. >>http://www.windowslive.com/skydrive/overview.html?ocid=TXT_TAGLM_WL_Refr e >sh_skydrive_packup_042008 >>-- >>AccessD mailing list >>AccessD at databaseadvisors.com >>http://databaseadvisors.com/mailman/listinfo/accessd >>Website: http://www.databaseadvisors.com > > > > > >-- >AccessD mailing list >AccessD at databaseadvisors.com >http://databaseadvisors.com/mailman/listinfo/accessd >Website: http://www.databaseadvisors.com