Parse `targetname` as if it were a asteroid.

        :return: (string or None, int or None, string or None);
          The designation, number, and name of the asteroid as derived from
          `self.targetname` are extracted into a tuple; each element that
          does not exist is set to `None`. Parenthesis in `self.targetname`
          will be ignored. Packed designations and numbers are unpacked.
        :example: the following table shows the result of the parsing:

        +--------------------------------+---------------------------------+
        |targetname                      |(desig, number, name)            |
        +================================+=================================+
        |1                               |(None, 1, None)                  |
        +--------------------------------+---------------------------------+
        |2 Pallas                        |(None, 2, Pallas)                |
        +--------------------------------+---------------------------------+
        |\(2001\) Einstein               |(None, 2001, Einstein)           |
        +--------------------------------+---------------------------------+
        |1714 Sy                         |(None, 1714, Sy)                 |
        +--------------------------------+---------------------------------+
        |2014 MU69                       |(2014 MU69, None, None)          |
        +--------------------------------+---------------------------------+
        |(228195) 6675 P-L               |(6675 P-L, 228195, None)         |
        +--------------------------------+---------------------------------+
        |4101 T-3                        |(4101 T-3, None, None)           |
        +--------------------------------+---------------------------------+
        |4015 Wilson-Harrington (1979 VA)|(1979 VA, 4015, Wilson-Harrington|
        +--------------------------------+---------------------------------+
        |J95X00A                         |(1995 XA, None, None)            |
        +--------------------------------+---------------------------------+
        |K07Tf8A                         |(2007 TA418, None, None)         |
        +--------------------------------+---------------------------------+
        |G3693                           |(None, 163693, None)             |
        +--------------------------------+---------------------------------+
        |2017 U1                         |(None, None, None)               |
        +--------------------------------+---------------------------------+

def parse_asteroid(self):
        """Parse `targetname` as if it were a asteroid.

        :return: (string or None, int or None, string or None);
          The designation, number, and name of the asteroid as derived from
          `self.targetname` are extracted into a tuple; each element that
          does not exist is set to `None`. Parenthesis in `self.targetname`
          will be ignored. Packed designations and numbers are unpacked.
        :example: the following table shows the result of the parsing:

        +--------------------------------+---------------------------------+
        |targetname                      |(desig, number, name)            |
        +================================+=================================+
        |1                               |(None, 1, None)                  |
        +--------------------------------+---------------------------------+
        |2 Pallas                        |(None, 2, Pallas)                |
        +--------------------------------+---------------------------------+
        |\(2001\) Einstein               |(None, 2001, Einstein)           |
        +--------------------------------+---------------------------------+
        |1714 Sy                         |(None, 1714, Sy)                 |
        +--------------------------------+---------------------------------+
        |2014 MU69                       |(2014 MU69, None, None)          |
        +--------------------------------+---------------------------------+
        |(228195) 6675 P-L               |(6675 P-L, 228195, None)         |
        +--------------------------------+---------------------------------+
        |4101 T-3                        |(4101 T-3, None, None)           |
        +--------------------------------+---------------------------------+
        |4015 Wilson-Harrington (1979 VA)|(1979 VA, 4015, Wilson-Harrington|
        +--------------------------------+---------------------------------+
        |J95X00A                         |(1995 XA, None, None)            |
        +--------------------------------+---------------------------------+
        |K07Tf8A                         |(2007 TA418, None, None)         |
        +--------------------------------+---------------------------------+
        |G3693                           |(None, 163693, None)             |
        +--------------------------------+---------------------------------+
        |2017 U1                         |(None, None, None)               |
        +--------------------------------+---------------------------------+
        """

        pat = ('(([1-2][0-9]{0,3}[ _][A-Z]{2}[0-9]{0,3})'  # designation [0,1]
               '|([1-9][0-9]{3}[ _](P-L|T-[1-3])))'  # Palomar-Leiden  [0,2,3]
               '|([IJKL][0-9]{2}[A-Z][0-9a-z][0-9][A-Z])'  # packed desig [4]
               '|([A-Za-z][0-9]{4})'  # packed number [5]
               '|([A-Z][A-Z]*[a-z][a-z]*[^0-9]*'
               '[ -]?[A-Z]?[a-z]*[^0-9]*)'  # name [6]
               '|([1-9][0-9]*(\b|$))')  # number [7,8]

        # regex patterns that will be ignored as they might cause
        # confusion
        non_pat = ('([1-2][0-9]{0,3}[ _][A-Z][0-9]*(\b|$))')  # comet desig

        if sys.version_info > (3, 0):
            raw = self.targetname.translate(str.maketrans('()', '  ')).strip()
        else:
            import string
            raw = self.targetname.translate(string.maketrans('()',
                                                             '  ')).strip()

        # reject non_pat patterns
        non_m = re.findall(non_pat, raw)
        # print('reject', raw, non_m)
        if len(non_m) > 0:
            for ps in non_m:
                for p in ps:
                    if p == '':
                        continue
                    raw = raw[:raw.find(p)] + raw[raw.find(p)+len(p):]

        # match target patterns
        m = re.findall(pat, raw)

        # print(raw, m)

        desig = None
        number = None
        name = None

        if len(m) > 0:
            for el in m:
                # designation
                if len(el[0]) > 0:
                    desig = el[0]
                # packed designation (unpack here)
                elif len(el[4]) > 0:
                    ident = el[4]
                # old designation style, e.g.: 1989AB
                    if (len(ident.strip()) < 7 and ident[:4].isdigit() and
                            ident[4:6].isalpha()):
                        desig = ident[:4]+' '+ident[4:6]
                        # Palomar Survey
                    elif ident.find("PLS") == 0:
                        desig = ident[3:] + " P-L"
                        # Trojan Surveys
                    elif ident.find("T1S") == 0:
                        desig = ident[3:] + " T-1"
                    elif ident.find("T2S") == 0:
                        desig = ident[3:] + " T-2"
                    elif ident.find("T3S") == 0:
                        desig = ident[3:] + " T-3"
                    # insert blank in designations
                    elif (ident[0:4].isdigit() and ident[4:6].isalpha() and
                          ident[4] != ' '):
                        desig = ident[:4]+" "+ident[4:]
                    # MPC packed 7-digit designation
                    elif (ident[0].isalpha() and ident[1:3].isdigit() and
                          ident[-1].isalpha() and ident[-2].isdigit()):
                        yr = str(_char2int(ident[0]))+ident[1:3]
                        let = ident[3]+ident[-1]
                        num = str(_char2int(ident[4]))+ident[5]
                        num = num.lstrip("0")
                        desig = yr+' '+let+num
                    # nothing to do
                    else:
                        desig = ident
                # packed number (unpack here)
                elif len(el[5]) > 0:
                    ident = el[5]
                    number = ident = int(str(_char2int(ident[0]))+ident[1:])
                # number
                elif len(el[7]) > 0:
                    if sys.version_info > (3, 0):
                        number = int(float(el[7].translate(str.maketrans('()',
                                                                         '  '))))
                    else:
                        import string
                        number = int(float(el[7].translate(string.maketrans('()',
                                                                            '  '))))

                # name (strip here)
                elif len(el[6]) > 0:
                    if len(el[6].strip()) > 1:
                        name = el[6].strip()

        return (desig, number, name)