Есть ли способ разделить строку на несколько разных строк?

#python #split #nlp

Вопрос:

Я пытаюсь сделать переводчик на пользовательский язык, и в данный момент я приближаюсь к точке , где я могу печатать the man sits with the woman и получать вывод de mno di felio colten aili , слово в слово the man the woman sits with .

Когда переводчик доходит до глагола, он добавляет его к verbo и предлог к prepo2 (это prepo2 не prepo по другим причинам). После того, как он закончит перевод слово в слово, он разделит его на все переводы the ( de и di ) и глагола, определенного ранее verbo . Затем он должен поставить глагол в конце и перейти к использованию предлога вместо глагола, а затем поставить его в конце.

Когда я вхожу , the man sits with the woman я получаю de mno di felio aili «нет colten «, когда я вхожу the man sits the woman (да, я не знаю правильного предложения, но это глагол, с которым я тестирую). Я просто получаю de mno colten di felio , и когда я вхожу the man is with the woman , я получаю de mno aili di felio .

Пытаюсь сделать это быстро, поэтому буду признателен за ответ 🙂

 import string
import re

NounM = {
    'man': 'mno',
    'rock': 'lehr',
    'dog': 'krua'
}

NounF = {
    'woman': 'felio',
    'chair': 'poen',
    'cat': 'keile'
}

Verb = {
    'sit': 'colt',
    'sing': 'alet'
}

Preposition = {
    'on': 'mit',
    'with': 'ail',
    'at': 'zal'
}

Pronoun = {
    'he': 'tse',
    'she': 'se',
    'i': 'ile',
    'me': 'men',
    'they': 'er',
    'it': 'ze',
    'you': 'jü'
}

Adjective = {
    'happy': 'kliony',
    'sad': 'probo',
    'good': 'klio',
    'bad': 'pro'
}

Article = {
    'that': 'arei',
    'those': 'sie'
}

Question = {
    'who': 'nej',
    'what': 'kär',
    'when': 'woin',
    'where': 'ten',
    'why': 'apr'
}

Skip = ('is', 'are', 'am')

Preposition_Replace = ('aile', 'aili', 'mite', 'miti')

Verb_Replace = ('colten', 'aleten')

def translate(j=None):
    sentence = input('Enter the sentence to turn into your custom language! ')
    split = sentence.split()
    translated_list = []
    translated_sentence = ''

    for index, word in enumerate(split):
        char = ''
        for a in string.punctuation:
            if str(a) in word:
                char = a
        if word in NounM:
            translated_sentence  = NounM[word]
        elif word in NounF:
            translated_sentence  = NounF[word]
        elif word in Verb:
            translated_sentence  = Verb[word]
            verbo = Verb[word]
        elif word in Preposition:
            translated_sentence  = Preposition[word]
            prepo = Preposition[word]
            try:
                c = split[index   1]
                while c not in NounM and c not in NounF:
                    a = 2
                    c = split[index   a]
                    a  = 1
                if c in NounM:
                    translated_sentence  = 'e'
                    prepo2 = prepo   'e'
                elif c in NounF:
                    translated_sentence  = 'i'
                    prepo2 = prepo   'i'
            except IndexError:
                pass
        elif word in Pronoun:
            translated_sentence  = Pronoun[word]
        elif word in Adjective:
            translated_sentence  = Adjective[word]
        elif word in Article:
            translated_sentence  = Article[word]
        elif word in Question:
            translated_sentence  = Question[word]
        elif word == 'the':
            c = split[index   1]
            while c not in NounM and c not in NounF:
                a = 2
                c = split[index   a]
                a  = 1
            if c in NounM:
                translated_sentence  = 'de'
            elif c in NounF:
                translated_sentence  = 'di'
            else:
                pass
        elif word == 'a':
            c = split[index   1]
            while c not in NounM and c not in NounF:
                    a = 2
                    c = split[index   a]
                    a  = 1
            if c in NounM:
                translated_sentence  = 'es'
            elif c in NounF:
                translated_sentence  = 'en'
            else:
                pass
        elif word in Skip:
            c = split[index   1]
            if c == 'not':
                split.remove('not')
                translated_sentence  = 'nen'
            else:
                pass
        elif word[len(word) - 1] == 's':
            word = word[:-1]
            if word in Verb:
                translated_sentence  = Verb[word]
                translated_sentence  = 'en'
                verbo = Verb[word]   'en'
            else:
                pass
        else:
            translated_sentence  = word
        word  = str(char)
        for i in translated_sentence:
            translated_list  = i
        translated_list  = str(char)
        if word == 'is' or word == 'are' or word == 'am':
            if c == 'not':
                translated_list  = ' '
            else:
                pass
        else:
            translated_list  = ' '
        translated_sentence = ''

    leng = len(translated_list) - 2
    final = translated_list[leng]
    if final in string.punctuation:
        translated_list.remove(final)

    translated_sentence = ''
    for i in translated_list:
        translated_sentence  = i

    if final in string.punctuation:
        translated_sentence  = final

    try:
        new_sentence2 = ''
        new_sentence = re.split('(?=de |di )' and ' ' verbo, translated_sentence)
        print(new_sentence)
        for i in new_sentence:
            new_sentence2  = i
        print(new_sentence2)
        new_sentence  = verbo
        new_sentence = re.split('(?=de |di )' and ' ' prepo2, new_sentence2)
        print(new_sentence)
        new_sentence.append(' ' prepo2)
        print(new_sentence)
        translated_sentence = ''
        for i in new_sentence:
            translated_sentence  = i
    except:
        pass

    print(translated_sentence)
    other_translate = input('Would you like to translate another sentence? y/n ')
    if other_translate == 'y':
        translate()


translate()

 

Основной код для разделяющей части:

 try:
        new_sentence2 = ''
        new_sentence = re.split('(?=de |di )' and ' ' verbo, translated_sentence)
        print(new_sentence)
        for i in new_sentence:
            new_sentence2  = i
        print(new_sentence2)
        new_sentence  = verbo
        new_sentence = re.split('(?=de |di )' and ' ' prepo2, new_sentence2)
        print(new_sentence)
        new_sentence.append(' ' prepo2)
        print(new_sentence)
        translated_sentence = ''
        for i in new_sentence:
            translated_sentence  = i
    except:
        pass
 

Ответ №1:

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

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

 import string
import re

NounM = {
    'man': 'mno',
    'rock': 'lehr',
    'dog': 'krua'
}

NounF = {
    'woman': 'felio',
    'chair': 'poen',
    'cat': 'keile'
}

Verb = {
    'sit': 'colt',
    'sing': 'alet'
}

Preposition = {
    'on': 'mit',
    'with': 'ail',
    'at': 'zal'
}

Pronoun = {
    'he': 'tse',
    'she': 'se',
    'i': 'ile',
    'me': 'men',
    'they': 'er',
    'it': 'ze',
    'you': 'jü'
}

Adjective = {
    'happy': 'kliony',
    'sad': 'probo',
    'good': 'klio',
    'bad': 'pro'
}

Article = {
    'that': 'arei',
    'those': 'sie'
}

Question = {
    'who': 'nej',
    'what': 'kär',
    'when': 'woin',
    'where': 'ten',
    'why': 'apr'
}

Skip = ('is', 'are', 'am')

Preposition_Replace = ('aile', 'aili', 'mite', 'miti')

Verb_Replace = ('colten', 'aleten')

gender = ''

def translate_word(word):
    global gender
    word, punctuation = check_punctuation(word)
    word = check_plurality(word)
    if word in NounM:
        gender = 'm'
        return f"de {NounM[word]}{punctuation}"
    elif word in NounF:
        gender = 'f'
        return f"de {NounF[word]}{punctuation}"
    elif word in Verb:
        ending = get_gendered_verb_ending()
        return f"{Verb[word]}{ending}{punctuation}"
    elif word in Preposition:
        return f"{Preposition[word]}{punctuation}"
    else:
        return

def check_punctuation(word):
    for p in string.punctuation:
        if str(p) in word:
            return word.replace(str(p), ''), str(p)
        else:
            return word, ''

def get_gendered_verb_ending():
    global gender
    if gender == 'm':
        return 'es'
    elif gender == 'f':
        return 'en'
    else:
        return ''

def check_plurality(word):
    print(word)
    if word[-1] == 's':
        return word[:-1]
    else:
        return word


def translate():
    sentence = input('Enter the sentence to turn into your custom language! ')
    split = sentence.split()
    translated = " ".join([translate_word(word) for word in split if translate_word(word) != None])
    print(translated)

translate()
 

Ответ №2:

Я бы предложил создать класс для слов, в котором вы можете хранить кучу семантических атрибутов (возможно, подклассы для частей языка). Создание словарей с экземплярами этих классов и связывание их вместе для перевода позволит вам реализовать общие правила, которые будут применяться ко всем категориям слов, тем самым уменьшая объем кода. Кроме того, вероятно, будет проще (по крайней мере, вначале) работать с полным написанием слов, чем пытаться составлять слова из стеблей, корней и морфем.

Например (не полная программа, просто общая иллюстрация):

Базовый класс для слов / словарей:

 class Word:
    NOUN    = "NOUN"
    VERB    = "VERB"
    PRONOUN = "PRONOUN"
    ADJ     = "ADJECTIVE"
    ADVERB  = "ADVERB"
    PREP    = "PREPOSITION"
    CONJ    = "CONJUNCTION"
    ARTICLE = "ARTICLE"

    MASCULINE = "M"
    FEMININE  = "F"
    NEUTRAL   = "N"

    SINGULAR = "S"
    DUAL     = "2"
    PLURAL   = "P"
    
    lexicon = dict()
    
    def __init__(self,spelling,part="NOUN",lang="EN",gender="N",plural="S"):
        self.part         = part
        self.spelling     = spelling.lower()
        self.language     = lang.upper()
        self.gender       = gender
        self.plural       = plural
        self.translations = set()
        vocabulary    = Word.lexicon.setdefault(self.language,dict())
        vocabulary.setdefault(self.spelling,[]).append(self)

    def noun(spelling,*args,**kwargs):         return Word(spelling,Word.NOUN,*args,**kwargs)
    def verb(spelling,*args,**kwargs):         return Word(spelling,Word.VERB,*args,**kwargs)
    def pronoun(spelling,*args,**kwargs):      return Word(spelling,Word.PRONOUN,*args,**kwargs)
    def adjective(spelling,*args,**kwargs):    return Word(spelling,Word.ADJ,*args,**kwargs)
    def adverb(spelling,*args,**kwargs):       return Word(spelling,Word.ADVERB,*args,**kwargs)
    def preposition(spelling,*args,**kwargs):  return Word(spelling,Word.PREP,*args,**kwargs)
    def conjunction(spelling,*args,**kwargs):  return Word(spelling,Word.CONJ,*args,**kwargs)
    def article(spelling,*args,**kwargs):      return Word(spelling,Word.ARTICLE,*args,**kwargs)

    def trans(self,*words,lang="CL"): # CL for Custom Language
        lang = lang.upper()
        for word in words:
            if isinstance(word,str):
                word = word.lower()
                vocabulary = Word.lexicon.setdefault(lang,dict())
                if word not in vocabulary:
                    word = Word(word,part=self.part,lang=lang,gender=self.gender,plural=self.plural)
                    self.translations.add(word)
                else:
                    self.translations.update(w for w in vocabulary[word] if w.part==self.part)
            else:
                self.translations.add(word)
        return self

    def getTrans(self,lang="CL"):
        return [w for w in self.translations if w.language==lang.upper()]
 

Метаданные:

 Word.noun('man',gender="M",plural=1).trans('mno')
Word.noun('rock').trans(Word('lehr',lang="CL",gender="M"))
Word.noun('dog').trans(Word.noun('krua',gender="M"))
Word.noun('woman',gender="F",plural=1).trans('felio')
Word.noun('chair').trans(Word.noun('poen',lang="CL",gender="F"))
Word.noun('cat').trans(Word('keile',lang="CL",gender="F"))
Word.verb('sit').trans('colt')
Word.verb('sits').trans('colt')
Word.verb('sing').trans('alet')
Word.preposition('on').trans('mit')
Word.preposition('with').trans('ail')
Word.preposition('at').trans('zal')
Word.pronoun('he',gender="M").trans('tse')
Word.pronoun('she',gender="M").trans('se')
Word.pronoun('i').trans('ile')
Word.pronoun('me').trans('men')
Word.pronoun('they',plural="P").trans('er')
Word.pronoun('it').trans('ze')
Word.pronoun('you').trans('jü')
Word.adjective('happy').trans('kliony')
Word.adjective('sad').trans('probo')
Word.adjective('good').trans('klio')
Word.adjective('bad').trans('pro')
Word.article('the').trans('de')
Word.article('that').trans('arei')
Word.article('those').trans('sie')
Word.adverb('who').trans('nej')
Word.adverb('what').trans('kär')
Word.adverb('when').trans('woin')
Word.adverb('where').trans('ten')
Word.adverb('why').trans('apr')
          
 

Синтаксический анализ и перевод:

 import re

sentence = "the man sits with the woman"

parsed = [Word.lexicon['EN'][w] for w in re.findall(r"w ",sentence)]

word2Word = [w[0].getTrans()[0].spelling for w in parsed]
print(*word2Word)
'de mno colt ail de felio'


verbPos  = next(i for i,w in enumerate(parsed) if w[0].part == Word.VERB)

SOV = word2Word[:verbPos] word2Word[verbPos 1:] word2Word[verbPos:verbPos 1]

print(*SOV) # Subject-Object-Verb
'de mno ail de felio colt'
 

Вы можете обогатить классы метаданных по мере необходимости, например, добавить подтипы к наречиям (например, вопросы), лица к глаголам и т.д. Дополнительные атрибуты помогут в построении общих правил, которые не зависят от правописания

Комментарии:

1. Спасибо, я попробую, хотя я едва понимаю две строчки в этой программе. Я посмотрю, как это работает.

Ответ №3:

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

Это называется «Обработка естественного языка», НЛП, и для этого существует множество библиотек. Я предлагаю вам проверить эти библиотеки, чтобы помочь вам проанализировать входные данные. Основной для Python называется NLTK, но есть также TextBlob, который стремится иметь более простой интерфейс.

Я использовал их недостаточно, чтобы давать какие-либо дополнительные рекомендации, кроме этого.