Как я могу сделать пробелы "рассчитывать" на этот скрипт для этого кода расшифровки? - PullRequest
0 голосов
/ 19 апреля 2020

Это код, написанный Александром Б. в моем предыдущем посте:

# Your dict
code_2 = {14: 'a', 15: 'b', 16: 'c', 24: 'd', 25: 'e', 26: 'f', 34: 'g',
     35:'h', 36: 'i', 44: 'j', 45: 'k', 46: 'l', 54: 'm', 55: 'n',
     56: 'ñ', 64: 'o', 65: 'p', 66: 'q', 74: 'r', 75: 's', 76: 't',
     84: 'u', 85: 'v', 86: 'w', 94: 'x', 95: 'y', 96: 'z'}

def decode_word(text):
# Check then length or the string
 if len(text) %2 != 0:
    raise ValueError("Text incorrect (must have a even length)")

# Split to a list of 2 numbers
text_l = ["".join([a,b]) for a,b in zip(text[::2], text[1::2])]

# Rebuild the world
word = "".join([code_2.get(int(key), "") for key in text_l])

# Check if all keys have been found
if len(word) < len(text)//2:
    print("WARNING: Some keys doesn't belong to 'code_2'.")
return word

Дело в том, что, скажем, я хочу "расшифровать" следующее: "3525464664 156415" (привет Боб) Если я введу это число во ввод, это выдаст ошибку («ПРЕДУПРЕЖДЕНИЕ: некоторые ключи не принадлежат« code_2 ».»). Я полагаю, что это происходит потому, что он не распознает «пробел» как ключ в code_2.

Есть ли способ, которым я могу расшифровать предложения с пробелами и всем, не получая эту ошибку? Возможно, часть кода или весь его придется изменить, я не против, я просто хочу, чтобы это сработало.

Спасибо за продвинутый:)

Ответы [ 3 ]

0 голосов
/ 19 апреля 2020
def decode_sentence(sentence):
    # Break the sentence into words
    words = sentence.split()
    # Decode words and use join to rebuild the sentence
    return ' '.join([decode_word(word) for word in words])

Pythons str.split() разбивает строку на список строк, используя пробел в качестве разделителя. Затем вы можете использовать функцию decode_word для декодирования каждого слова и join их обратно вместе с пробелами между.

Полный пример:

# Your dict
code_2 = {14: 'a', 15: 'b', 16: 'c', 24: 'd', 25: 'e', 26: 'f', 34: 'g',
     35:'h', 36: 'i', 44: 'j', 45: 'k', 46: 'l', 54: 'm', 55: 'n',
     56: 'ñ', 64: 'o', 65: 'p', 66: 'q', 74: 'r', 75: 's', 76: 't',
     84: 'u', 85: 'v', 86: 'w', 94: 'x', 95: 'y', 96: 'z'}

def decode_sentence(sentence):
    # Break the sentence into words
    words = sentence.split()
    # Decode words and use join to rebuild the sentence
    return ' '.join([decode_word(word) for word in words])

def decode_word(text):
    # Check then length or the string
    if len(text) %2 != 0:
        raise ValueError("Text incorrect (must have a even length)")

    # Split to a list of 2 numbers
    text_l = ["".join([a,b]) for a,b in zip(text[::2], text[1::2])]

    # Rebuild the world
    word = "".join([code_2.get(int(key), "") for key in text_l])

    # Check if all keys have been found
    if len(word) < len(text)//2:
        print("WARNING: Some keys doesn't belong to 'code_2'.")
    return word

И затем вы можете выполнить:

decode_sentence('1415 1624')

>>>'ab cd'
0 голосов
/ 19 апреля 2020

Если вы хотите перевести только числовую часть кодировки, используйте регулярное выражение для захвата цифр и просто напишите функцию для работы с этим единственным словом и возврата перевода. re.sub может сделать замену. Я также сделал кодировщик:

import re

code_2_decode = {14: 'a', 15: 'b', 16: 'c', 24: 'd', 25: 'e', 26: 'f', 34: 'g',
                 35:'h', 36: 'i', 44: 'j', 45: 'k', 46: 'l', 54: 'm', 55: 'n',
                 56: 'ñ', 64: 'o', 65: 'p', 66: 'q', 74: 'r', 75: 's', 76: 't',
                 84: 'u', 85: 'v', 86: 'w', 94: 'x', 95: 'y', 96: 'z'}

# To test encoding, build a code point to replacement map.
# Entries look like {'a':'14', 'b':'16', ...}
code_2_encode = dict({k:f'{v:02d}' for k,v in zip(code_2_decode.values(),code_2_decode.keys())})

# str.translate will map Unicode ordinals to a string.  Build the map it requires.
# Entries look like {97:'14', 98:'15', ...}
# Note: U+0097 is the Unicode ordinal of 'a', U+0098 is the Unicode ordinal of 'b', ...
code_2_xlat = str.maketrans(code_2_encode)

def encode(s):
    return s.translate(code_2_xlat)

def decode(s):

    # replacement function that works on one "word"
    def replace(m):

        word = m.group(0)

        if len(word) % 2:
            raise ValueError('word length must be even')

        # Use a list comprehension to iterate through the "word" string
        # two characters-at-a-time.  Convert the two-character string to
        # an integer and look up the replacement.  finally, join everything
        # together.
        return ''.join([code_2_decode[int(word[i:i+2])]
                        for i in range(0,len(word),2)])

    # Match strings of digits and call the replacement function on string.
    return re.sub(r'\d+',replace,s)

test_string = 'hello bob'
print(encode(test_string))
print(decode(test_string))

test_string = 'hello, world!'
print(encode(test_string))
print(decode(test_string))

Вывод:

3525464664 156415
hello bob
3525464664, 8664744624!
hello, world!
0 голосов
/ 19 апреля 2020

Один из методов - использовать совпадение с регулярным выражением для \ d +, а затем для каждой группы захвата «расшифровывать» его по отдельности. См. Python заменить шаблон строки на вывод функции например.

Это может быть метод decode_sentence, который будет вызывать decode_word в отдельных совпадениях. (Или: выберите свое собственное имя.)

def decode_sentence(encoded_string):
  # literal almost-verbatim adaptation of the code
  # from the accepted answer in the linked question.. patterns.
  def my_replace(match):
    word = match.group()
    return decode_word(word)

  return re.sub(r'@\d+', my_replace, encoded_string)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...