import re


def fingerprint(x, special_characters=''):
    """
    Returns a lowercase, alphanumeric representation of ``x``

    Usage:
      >>> from etl_toolbox.cleaning_functions import fingerprint
      >>> fingerprint('(Aa_Bb_Cc)')
      'aabbcc'

    :param x:
        The object to be fingerprinted. Will be cast to a string using
        ``str(x)``.

    :param special_characters:
        A string of special characters to preserve while creating the
        fingerprint of ``x``. Any special characters which are individually
        meaningful for the data should be included here.

          >>> fingerprint('(Aa_Bb_Cc)', special_characters='_')
          'aa_bb_cc'

        .. note::
           An example of where this might be useful is when fingerprinting
           column labels on a data set. Some datasets use ``$`` as a label for
           price/cost or ``#`` as a label for phone number or id number. In
           that case, ``special_characters`` should be set to ``'#$'`` so that
           those values are preserved.

    :type special_characters: string, optional

    :return:
        Returns a string.
    """
    remove_regex = r'[^0-9a-z{}]'.format(re.escape(special_characters))

    return re.sub(remove_regex, '', str(x).lower())