Based on https://github.com/commonsense/simplenlp/blob/master/simplenlp/euro.py#L132
    
    :param text: A single ``str``/``Unicode`` containing the sentence (well, might work on any arbitrary text) you'd like to untokenize.
    :returns: A UTF8-encoded, regular expression-friendly, untokenized version of ``text``.

    .. seealso:: https://github.com/EducationalTestingService/stanford-thrift/blob/master/README_tokenizer.md which isn't actually used here (much slower than this approach)

def untokenize(text):
    '''
    Based on https://github.com/commonsense/simplenlp/blob/master/simplenlp/euro.py#L132
    
    :param text: A single ``str``/``Unicode`` containing the sentence (well, might work on any arbitrary text) you'd like to untokenize.
    :returns: A UTF8-encoded, regular expression-friendly, untokenized version of ``text``.

    .. seealso:: https://github.com/EducationalTestingService/stanford-thrift/blob/master/README_tokenizer.md which isn't actually used here (much slower than this approach)
    '''
    text = text.encode('utf8')

    step1 = re.sub(r'([\*\?])', r'\\\\\1', text.decode("utf8"), re.U)
 
    step2 = step1.replace("`` ", '"\s*').replace(" ''", '"\s*')
    step2 = step2.replace(" -LRB- ", " [\[\(]")
    step2 = re.sub(r' -RRB- ?', r"[\]\)] ", step2)

    step2a = re.sub(r'\.\.\. *', r'[\.…]{1,3}', step2, re.U)

    step3 = re.sub(r' \\*([.,:;?!%]+)([ \'"`\*])', r"\1\2", step2a)
    step4 = re.sub(r' \\*([,:;?!%]+)$', r'\s*\\' + r"\1", step3)

    step5 = re.sub(r" '", r"'", step4)
    step5 = re.sub(r" n't", r"n't", step5)
    step5 = step5.replace("can not", "cannot")

    step6 = re.sub(r'( *)` ', r"\1'", step5)

    step7 = step6.strip()

    step8 = re.sub(r' \*$', r'', step7)
    
    step9 = re.sub(r' ([^\\\*\+])', r'\s+\1', step8)
    step9 = re.sub(r'\\s[\+\*]$', r'', step9)

    return step9