Convert string x to the most useful type, i.e. int, float or unicode string.

    If x is a quoted string (single or double quotes) then the quotes are
    stripped and the enclosed string returned. The string can contain any
    number of quotes, it is only important that it begins and ends with either
    single or double quotes.

    *percentify* = ``True`` turns "34.4%" into the float 0.344.

    .. Note::

       Strings will be returned as Unicode strings (using
       :func:`unicode`), based on the *encoding* argument, which is
       utf-8 by default.

def besttype(x, encoding="utf-8", percentify=True):
    """Convert string x to the most useful type, i.e. int, float or unicode string.

    If x is a quoted string (single or double quotes) then the quotes are
    stripped and the enclosed string returned. The string can contain any
    number of quotes, it is only important that it begins and ends with either
    single or double quotes.

    *percentify* = ``True`` turns "34.4%" into the float 0.344.

    .. Note::

       Strings will be returned as Unicode strings (using
       :func:`unicode`), based on the *encoding* argument, which is
       utf-8 by default.

    """
    def unicodify(x):
        return to_unicode(x, encoding)
    def percent(x):
        try:
            if x.endswith("%"):
                x = float(x[:-1]) / 100.
            else:
                raise ValueError
        except (AttributeError, ValueError):
            raise ValueError
        return x

    x = unicodify(x)  # make unicode as soon as possible
    try:
        x = x.strip()
    except AttributeError:
        pass
    m = re.match(r"""(?P<quote>['"])(?P<value>.*)(?P=quote)$""", x)  # matches "<value>" or '<value>' where <value> COULD contain " or '!
    if m is None:
        # not a quoted string, try different types
        for converter in int, float, percent, unicodify:   # try them in increasing order of lenience
            try:
                return converter(x)
            except ValueError:
                pass
    else:
        # quoted string
        x = unicodify(m.group('value'))
    return x