1

So I am using a Magtek USB reader that will read card information,

As of right now I can swipe a card and I get a long string of information that goes into a Tkinter Entry textbox that looks like this

%B8954756016548963^LAST/FIRST INITIAL^180912345678912345678901234?;8954756016548963=180912345678912345678901234?

All of the data has been randomized, but that's the format

I've got a tkinter button (it gets the text from the entry box in the format I included above and runs this)

    def printCD(self):
        print(self.carddata.get())
        self.card_data_get = self.carddata.get()
        self.creditnumber = 
        self.card_data_get[self.card_data_get.find("B")+1:
        self.card_data_get.find("^")]
        print(self.creditnumber)
        print(self.card_data_get.count("^"))

This outputs:

%B8954756016548963^LAST/FIRST INITIAL^180912345678912345678901234?;8954756016548963=180912345678912345678901234?
8954756016548963

This yields no issues, but if I wanted to get the next two variables firstname, and lastname

I would need to reuse self.variable.find("^") because in the format it's used before LAST and after INITIAL

So far when I've tried to do this it hasn't been able to reuse "^"

Any takers on how I can split that string of text up into individual variables:

Card Number

First Name

Last Name

Expiration Date

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
ecorp
  • 103
  • 13
  • So there's two lines there, stack made it hard to format it, it pulls the text from "B" to "^" (which is continued on the next line) and saves it to the variable self.creditnumber – ecorp Jul 29 '18 at 17:58

2 Answers2

1

Regex will work for this. I didn't capture everything because you didn't detail what's what but here's an example of capturing the name:

import re
data = "%B8954756016548963^LAST/FIRST INITIAL^180912345678912345678901234?;8954756016548963=180912345678912345678901234?"

matches = re.search(r"\^(?P<name>.+)\^", data)

print(matches.group('name'))
# LAST/FIRST INITIAL

If you aren't familiar with regex, here's a way of testing pattern matching: https://regex101.com/r/lAARCP/1 and an intro tutorial: https://regexone.com/

But basically, I'm searching for (one or more of anything with .+ between two carrots, ^).

Actually, since you mentioned having first and last separate, you'd use this regex:

\^(?P<last>.+)/(?P<first>.+)\^

This question may also interest you regarding finding something twice: Finding multiple occurrences of a string within a string in Python

Zev
  • 3,423
  • 1
  • 20
  • 41
  • I can't thank you enough! Sorry if my question was complicated or not explained well enough, you've given me the resources I need! – ecorp Jul 30 '18 at 12:30
  • @JakeWenzel No problem! The question was fine. I just couldn't quickly spot the expiration date. If you feel the question is answered, please be sure to select one of the answers. – Zev Jul 30 '18 at 12:40
  • @Zev absolutely, so real quick, if I wanted to reference from "^" to "/" for last name and then "/" to "^" for first name I would just use `\^(?P.+)/(?P.+)\^` ? – ecorp Jul 30 '18 at 12:55
  • Yes! Give it a try and let me know if you have any trouble. You'd access them as `matches.group('last')` or `matches.group('first')` – Zev Jul 30 '18 at 12:57
  • So it worked, I'm having a hard time doing this with the credit card number though. `re.search(r"\d(?P.+)\^` It automatically goes to the second '^' – ecorp Jul 30 '18 at 15:31
  • So instead of creditcard being 8954756016548963 it is 8954756016548963^LAST/FIRST INITIAL – ecorp Jul 30 '18 at 15:37
  • You can find all the groups at once (like @PatrickArtner showed) or modify your query to be `\d(?P.+)\^.+\^` so it looks for numbers before two carrots rather than just one. – Zev Jul 30 '18 at 16:02
0

If you find regex difficult you can divide the problem into smaller pieces and attack one at a time:

data = '%B8954756016548963^LAST/FIRST INITIAL^180912345678912345678901234?;8954756016548963=180912345678912345678901234?'

pieces = data.split('^')    # Divide in pieces, one of which contains name

for piece in pieces:
    if '/' in piece:
        last, the_rest = piece.split('/')
        first, initial = the_rest.split()
        print('Name:', first, initial, last)
    elif piece.startswith('%B'):
        print('Card no:', piece[2:])
figbeam
  • 7,001
  • 2
  • 12
  • 18