Получение префикса из имен Нидерландов

У меня есть социальная сеть с пользователями из Нидерландов на Django. С помощью моего сайта я могу получить имя Нидерландов, например, Jap van der Stael, а мне нужно получить только часть van der. Для этого имени это не проблема, но как получить инфикс от такого имени, как Jap van der Vulpen - Odijk?

На данный момент у меня есть следующий код:

last_name_1 = 'van der Vulpen'
last_name_2 = 'van der Vulpen - Odijk'

' '.join(last_name_1.split()[:-1] -> 'van der'
' '.join(last_name_2.split()[:-1] -> 'van der Vulpen -'

Как вернуть чистый префикс для фамилии_2

Некоторые возможные примеры имен:

nijveldt - affourtit
van Eldik
deHart
NIEUWBURG
Heuvel van den
van deven
Koerten - de Jong
vanBARNEVELD

Насколько я понимаю, в Нидерландах эти средние части всегда пишутся со строчной буквы. Таким образом, это должно работать:

def get_prefix(name):
    return " ".join([x for x in name.split(" ") if x.islower()])

Приятным моментом в этом решении является то, что "-" не считается строчным, поэтому он также отфильтровывается. Однако, если "правильные" части имени не являются прописными, то у нас возникает проблема. Чтобы решить эту проблему, нам придется рассматривать строку в целом:

def get_prefix_v2(name):
    parts = name.split(" ")
    i = len(parts) - 2
    while i >= 0:
        if parts[i] == "-":
            i -= 2
        else:
            return " ".join(parts[1:i+1])

Однако эта функция все еще предполагает, что у вас есть имя и фамилия. Можно рассмотреть другой вариант - найти допустимые значения префикса и вытащить его таким образом:

valid_prefix_parts = set(["van", "de", "den"])
def get_prefix_v3(name):
    parts = []
    last_name_found = False
    for part in name.split(" "):
        if part in valid_prefix_parts:
            last_name_found = True
            parts.append(part)
        else:
            prefixes = list(filter(lambda prefix: part.startswith(prefix), valid_prefix_parts))
            if any(prefixes):
                parts.append(prefixes[0])
            elif last_name_found:
                break
    return " ".join(parts)
Вернуться на верх