def split(langs, str, sep=';'):
    '''Split str at sep to match a given list of langs

    >>> split(['de'], 'text de')
    {'de': 'text de'}
    >>> split(['de'], 'text;;de')
    {'de': 'text;;de'}
    >>> split(['de', 'en'], 'text de')
    {'de': 'text de', 'en': 'text de'}
    >>> split(['de', 'en'], 'text de;text en')
    {'de': 'text de', 'en': 'text en'}
    >>> split(['de', 'en'], 'text de;text en;text xx')
    {'de': 'text de', 'en': 'text en'}
    >>> split(['de', 'en'], 'text;;de;text;;en')
    {'de': 'text;de', 'en': 'text;en'}
    >>> split(['de', 'en'], 'text de;;;text en;;')
    {'de': 'text de;', 'en': 'text en;'}
    >>> split(['de', 'en'], 'text de;;;;;text en;;;;')
    {'de': 'text de;;', 'en': 'text en;;'}
    >>> split(['de', 'en'], ';')
    {'de': '', 'en': ''}
    >>> split(['de', 'en'], ';a')
    {'de': '', 'en': 'a'}
    >>> split(['de', 'en'], 'a;')
    {'de': 'a', 'en': ''}
    >>> split(['de', 'en'], ';;')
    {'de': ';', 'en': ';'}
    >>> split(['de', 'en'], ';;a')
    {'de': ';a', 'en': ';a'}
    >>> split(['de', 'en'], 'a;;')
    {'de': 'a;', 'en': 'a;'}
    '''
    if len(langs) < 2:
        return {langs[0]: str}
    split_chars = [[]]
    i = 0
    while i < len(str):
        if str[i] == sep:
            if i+1 < len(str) and str[i+1] == sep:
                split_chars[-1].append(sep)
                i += 1
            else:
                split_chars.append([])
        else:
            split_chars[-1].append(str[i])
        i += 1
    splits = [''.join(chars) for chars in split_chars]
    splits.extend(splits[:1]*(len(langs)-len(splits)))
    return dict(zip(langs, splits))


def extract(langs, str, lang, sep=';'):
    '''Extract a language from a string separating it at sep

    >>> extract(['de'], 'text de', 'de')
    'text de'
    >>> extract(['de'], 'text de', 'xx')
    'text de'
    >>> extract(['de'], 'text;;de', 'xx')
    'text;;de'
    >>> extract(['de', 'en'], 'text de', 'de')
    'text de'
    >>> extract(['de', 'en'], 'text de', 'en')
    'text de'
    >>> extract(['de', 'en'], 'text de;text en', 'de')
    'text de'
    >>> extract(['de', 'en'], 'text de;text en', 'en')
    'text en'
    >>> extract(['de', 'en'], 'text de;text en', 'xx')
    'text de'
    >>> extract(['de', 'en'], 'text de;text en;text xx', 'xx')
    'text de'
    >>> extract(['de', 'en'], 'text;;de;text;;en', 'de')
    'text;de'
    >>> extract(['de', 'en'], 'text de;;;text en;;', 'de')
    'text de;'
    >>> extract(['de', 'en'], 'text de;;;;;text en;;;;', 'de')
    'text de;;'
    >>> extract(['de', 'en'], 'text;;de;text;;en', 'en')
    'text;en'
    >>> extract(['de', 'en'], 'text de;;;text en;;', 'en')
    'text en;'
    >>> extract(['de', 'en'], 'text de;;;;;text en;;;;', 'en')
    'text en;;'
    >>> extract(['de', 'en'], ';', 'de')
    ''
    >>> extract(['de', 'en'], ';', 'en')
    ''
    >>> extract(['de', 'en'], ';a', 'de')
    ''
    >>> extract(['de', 'en'], ';a', 'en')
    'a'
    >>> extract(['de', 'en'], 'a;', 'de')
    'a'
    >>> extract(['de', 'en'], 'a;', 'en')
    ''
    >>> extract(['de', 'en'], ';;', 'de')
    ';'
    >>> extract(['de', 'en'], ';;', 'en')
    ';'
    >>> extract(['de', 'en'], ';;a', 'de')
    ';a'
    >>> extract(['de', 'en'], ';;a', 'en')
    ';a'
    >>> extract(['de', 'en'], 'a;;', 'de')
    'a;'
    >>> extract(['de', 'en'], 'a;;', 'en')
    'a;'
    '''
    if len(lang) < 2:
        return str
    splits = split(langs, str, sep=sep)
    if lang not in langs:
        return splits[langs[0]]
    return splits[lang]
