Share This
Связаться со мной
Крути в низ
Categories
//Регулярное выражение для проверки римских чисел (на Python)

Регулярное выражение для проверки римских чисел (на Python)

09.05.2021Category : Python

reguljarnoe vyrazhenie dlja proverki rimskih chisel na python b604324 - Регулярное выражение для проверки римских чисел (на Python)

Многим в детстве нравились приключенческие игры с головоломками и загадками. Найти решение было личным вызовом, а его поиски напоминали охоту за сокровищами. И когда, наконец, загадка была разгадана, ощущения были потрясающими!

reguljarnoe vyrazhenie dlja proverki rimskih chisel na python 0f8b265 - Регулярное выражение для проверки римских чисел (на Python)Повсеместно записывать число «четыре» как «IV» стали только в XIX веке, до этого наиболее часто употреблялась запись «IIII». 

Регулярные выражения могут помочь ощутить тот же детский восторг. (Регулярные выражения на английском языке — regular expressions, сокращенно — regex, — прим. перев.). Их использование открывает множество возможностей. К тому же, когда читаешь регулярное выражение и понимаешь, что оно означает, — это как расшифровать египетский иероглиф, как внезапно обнаружить, что знаешь чужой язык!

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

Как формируются римские числа

Римские числа записываются римскими цифрами, которые вы видите в табличке:

Тысячи Сотни Десятки Единицы
1 M C X I
2 MM CC XX II
3 MMM CCC XXX III
4 CD LX IV
5 D L V
6 DC LX VI
7 DCC LXX VII
8 DCCC LXXX VIII
9 CM XC IX

Кажется, цифры для обозначения тысяч заканчиваются на [MMM], а значит, самое большое число, которое можно написать римскими цифрами, это 3999 ([MMMCMXCIX]). Для целей этой статьи и решения нашей задачи будем считать, что римские числа укладываются в диапазон от 1 до 3999. (На самом деле есть и большие числа, подробнее об этом можно почитать в Википедии, — прим. перев.).

Что нужно понимать, так это важность порядка в расположении римских цифр. Если вы поставите их не в том порядке, вы напишете неправильное или вообще нечитаемое число. Как было показано в таблице выше, число начинается с тысяч [M] 1000, затем идут сотни [D/C] 500/100, затем десятки [L/X] 50/10 и, наконец, единицы [V/I] 5/1.

Но это еще далеко не все! Цифры могут повторяться не больше трех раз подряд (например, 300 = CCC), а потом заменяются комбинацией двух цифр (400 = CD, а не CCCC). Дальше вы можете продолжать использовать C, но уже перед M, как в числе 900 (CM).

Не так-то все просто, верно?

reguljarnoe vyrazhenie dlja proverki rimskih chisel na python af3fcfd - Регулярное выражение для проверки римских чисел (на Python)

Ладно, давайте повторим наши условия

  • Римские числа — это числа в диапазоне от [I] 1 до [MMMCMXCIX] 3999
  • Цифры в числе располагаются в строго определенном порядке: [M] 1000 / [D] 500 / [C] 100 / [L] 50 / [X] 10 / [V] 5 / [I] 1
  • Любая отдельная цифра не может повторяться больше трех раз подряд, на четвертый раз используется уже пара цифр
  • Пары цифр бывают следующие: [CM] 900 / [CD] 400 / [XC] 90 / [XL] 40 / [IX] 9 / [IV] 4

Вы замечаете, как начинает вырисовываться регулярное выражение?

Давайте переведем это в код

Мы будем использовать один очень полезный при написании регулярных выражений тег, — VERBOSE или re.X). Он позволяет разделять паттерн на несколько строк, чтобы сделать его более читаемым. Давайте попробуем!

import re  def is_roman_number(num):      pattern = re.compile(r"""                                    ^M{0,3}                                 (CM|CD|D?C{0,3})?                                 (XC|XL|L?X{0,3})?                                 (IX|IV|V?I{0,3})?$             """, re.VERBOSE)      if re.match(pattern, num):         return True      return False

Вах! Это уже потрясающе выглядит! Рассмотрим строки паттерна подробнее:

  • ^M{0,3} = От 0 до 3 символов [M] в начале строки [^]
  • (CM|CD|D?C{0,3})? = Одна пара [CM] или одна пара [CD], или [D], за которой идет от 0 до 3 символов [C]. Каждый элемент является опциональным [?], так же, как и весь блок [()?]
  • (XC|XL|L?X{0,3})? = Одна пара [XC] или одна пара [XL] или [L], за которой идет от 0 до 3 символов [X]. Каждый элемент является опциональным [?], так же, как и весь блок [()?]
  • (IX|IV|V?I{0,3})?$ = Одна пара [IX] или одна пара [IV] или [V], за которой идет от 0 до 3 символов [I]. Каждый элемент является опциональным [?], так же, как и весь блок [()?], стоящий в конце строки [$]

Протестируем наш код

Используем fstring для вызова функции и сравнения строки с паттерном:

num_valid = 'MMDCCLXXIII' num_invalid = 'CCCMMVIIVV'  print(f"{num_valid} - это {'не ' if not is_roman_number(num_valid) else ''}римское число") print(f"{num_invalid} - это {'не ' if not is_roman_number(num_invalid) else ''}римское число")  # Вывод: # MMDCCLXXIII - это римское число # CCCMMVIIVV - это не римское число

Не так уж и плохо! А теперь посмотрите на это и попробуйте сказать, что это не самая прекрасная вещь, которую вы видели в жизни!

^M{0,3}(CM|CD|D?C{0,3})?(XC|XL|L?X{0,3})?(IX|IV|V?I{0,3})?$'

reguljarnoe vyrazhenie dlja proverki rimskih chisel na python 0c3c434 - Регулярное выражение для проверки римских чисел (на Python)

Свежие вакансии по Python

Для тех, кто хочет найти работу Junior Python Developer

Подписаться ×

  • 1 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Свежие комментарии

    Рубрики

    About Author 01.

    Roman Spiridonov
    Roman Spiridonov

    Привет ! Мне 38 лет, я работаю в области информационных технологий более 4 лет. Тут собрано самое интересное.

    Our Instagram 04.

    Categories 05.

    © Speccy 2020 / All rights reserved

    Связаться со мной
    Close