使用Python使用Regex解析罗马数字

时间:2014-05-17 03:58:26

标签: python regex parsing

我需要将罗马数字字符串转换为整数。我不知道如何开始,只是我需要使用正则表达式。

import re

def romanNumeralToInt(romanNum):
    romanNum = romanNum.upper()
    totalValue = 0

我确实需要进行一系列测试:

def test():
    print("Tests started.")
    x = "III"
    "" if romanNumeralToInt(x) == 3 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "IV"
    "" if romanNumeralToInt(x) == 4 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "IX"
    "" if romanNumeralToInt(x) == 9 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "C"
    "" if romanNumeralToInt(x) == 100 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "CC"
    "" if romanNumeralToInt(x) == 200 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "CCC"
    "" if romanNumeralToInt(x) == 300 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "CD"
    "" if romanNumeralToInt(x) == 400 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "D"
    "" if romanNumeralToInt(x) == 500 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "DC"
    "" if romanNumeralToInt(x) == 600 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "DCC"
    "" if romanNumeralToInt(x) == 700 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "DCCC"
    "" if romanNumeralToInt(x) == 800 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "M"
    "" if romanNumeralToInt(x) == 1000 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "LXI"
    "" if romanNumeralToInt(x) == 61 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "IC"
    "" if romanNumeralToInt(x) == 99 else print(x + " - " + str(romanNumeralToInt(x)))
    x = "MMCI"
    "" if romanNumeralToInt(x) == 2101 else print(x + " - " + str(romanNumeralToInt(x)))
    print("Tests ended.")

2 个答案:

答案 0 :(得分:0)

您可以使用正则表达式将CCMMI之类的字符串拆分为三个部分:最大值的字符串(“MM”),要删除的任何内容,以及要添加的任何内容。< / p>

然后你有一个小问题,就是找到单个值(MM)的字符串的值,以及找到两个不包含“M”的罗马数字值的两个小问题( CCI)。你可以这样划分和征服,直到空字符串的基本情况为0。

这是一个次优的实现,它比必要的更多匹配并且没有输入验证(不想破坏所有的乐趣):

import re

values = [ ("M", 1000), ("D", 500), ("C", 100),
    ("L", 50), ("X", 10), ("V", 5), ("I", 1) ]

def romanNumeralToInt(romanNum):
    for (c, v) in values:
        match = re.match("(.*?)(" + c + "+)(.*)", romanNum)   
        if match:                                          
            return len(match.group(2)) * v \
                - romanNumeralToInt(match.group(1)) \
                + romanNumeralToInt(match.group(3))
    return 0

答案 1 :(得分:0)

使用正则表达式:

import re
roman = {'I' : 1, 'V' : 5, 'X' : 10, 'L' : 50,
         'C' : 100, 'D' : 500, 'M' : 1000,
         'IV' : 4, 'IX' :9, 'XL' : 40, 'XC' : 90,
         'CD': 400, 'CM' : 900}

def convert(numerals):
    total = 0
    specials = re.compile('IV|IX|XL|XC|CD|CM')
    for special in specials.findall(numerals): 
        total += roman[special]
        numerals = numerals.replace(special, '', 1)
    return total + sum(roman[n] for n in numerals)

没有正则表达式:

def convert(numerals):
    total = 0
    for special in ('IV', 'IX', 'XL', 'XC', 'CD', 'CM'):
        if numerals.count(special):
            total += roman[special] * numerals.count(special)
            numerals = numerals.replace(special, '')
    return total + sum(roman[n] for n in numerals)