【问题标题】:Using Python to parse roman numerals using Regex [duplicate]使用 Python 使用 Regex 解析罗马数字 [重复]
【发布时间】:2014-05-17 03:58:25
【问题描述】:

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

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.")

【问题讨论】:

  • 到目前为止你有什么?一个好的起点是在维基百科上查看如何手动转换这些,然后尝试编写你正在做的事情。如果您只是在寻找执行此操作的代码,谷歌搜索,一切都结束了。
  • @U2EF1 我试过了,我找不到任何使用正则表达式的例子
  • 您“需要”使用正则表达式是因为您认为这是最好的方法(我不同意)还是因为它是作业的一部分?
  • @Kryptos 你知道如何使用正则表达式吗?也许你可以看看文档。
  • 我知道“如何”在一般情况下使用正则表达式,但我无法弄清楚具体数字,是的,我需要使用正则表达式

标签: python regex parsing


【解决方案1】:

您可以使用正则表达式将CCMMI 之类的字符串拆分为三部分:最大值字符串(“MM”)、要减去的左侧以及要添加的右侧。

然后,您会遇到一个小问题,即查找单个值的字符串的值 (MM),以及查找不包含“M”的两个罗马数字的值的两个较小问题 (@987654323 @ 和 I)。您可以像这样分而治之,直到空字符串的基本情况为 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

【讨论】:

    【解决方案2】:

    使用正则表达式:

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-22
      • 2011-11-03
      • 2015-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多