2012-04-10 59 views
3

我有以下字符串:轉換包含羅馬數字的字符串到整數相當於

str = "MMX Lions Television Inc" 

我需要把它轉換成:

conv_str = "2010 Lions Television Inc" 

我有以下功能轉換羅馬數字轉換成其等於整數:

numeral_map = zip(
    (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1), 
    ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') 
) 

def roman_to_int(n): 
    n = unicode(n).upper() 

    i = result = 0 
    for integer, numeral in numeral_map: 
     while n[i:i + len(numeral)] == numeral: 
      result += integer 
      i += len(numeral) 
    return result 

我該如何使用re.sub來做在這裏得到正確的字符串?

(注:我試着用這裏所描述的regexHow do you match only valid roman numerals with a regular expression?但它不工作)

+1

有沒有你不使用直線上升的字典牽着你的羅馬數字,然後使用鍵來獲取值的原因嗎? – Makoto 2012-04-10 17:38:15

+2

@Makoto:是的,因爲提取數字的順序是相關的。 '1000'必須是'M' - 它不能是'DD'或'CCCCCCCCCC',如果你使用字典,你會得到它。至少從十進制到羅馬數字的轉換,您需要固定的數字順序。 – 2012-04-10 17:45:57

回答

2

re.sub()可以接受的函數作爲替換,該函數將接收單個參數,它是匹配對象,並應該返回一個替換字符串。你已經有了一個函數來將一個羅馬數字字符串轉換爲一個int,所以這並不困難。

你的情況,你想這樣的功能:

def roman_to_int_repl(match): 
    return str(roman_to_int(match.group(0))) 

現在你可以修改從你鏈接的問題,正則表達式,這樣它會找到一個更大的字符串中匹配:

s = "MMX Lions Television Inc" 
regex = re.compile(r'\b(?=[MDCLXVI]+\b)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b') 
print regex.sub(roman_to_int_repl, s) 

這裏是一個版本的正則表達式的,不會替換字符串中的「有限責任公司」:

regex = re.compile(r'\b(?!LLC)(?=[MDCLXVI]+\b)M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b') 

ÿ歐也可以使用正則表達式原來用修改替換功能:

def roman_to_int_repl(match): 
    exclude = set(["LLC"]) # add any other strings you don't want to replace 
    if match.group(0) in exclude: 
     return match.group(0) 
    return str(roman_to_int(match.group(0))) 
+0

謝謝,這個作品很棒。你會如何讓're'忽略「LLC」? – David542 2012-04-10 18:05:26

+0

在正則表達式的開頭,添加下面的'(?!LLC \ b)',如果是一個更大的列表,你想禁止,你可以使用類似下面的內容:'(?!(LLC | XXX | I )\ b)中' – 2012-04-10 18:08:40

5

尋找一個共同的功能/庫時,請務必嘗試Python Package Index

這是list of modules related to the keyword 'roman'

例如「romanclass」具有實現該變換的類,引用的文檔:

So a programmer can say: 

>>> import romanclass as roman 

>>> two = roman.Roman(2) 

>>> five = roman.Roman('V') 

>>> print (two+five) 

and the computer will print: 

VII 
+0

謝謝,這將如何應用於上述問題? – David542 2012-04-10 17:55:59

+0

猜測:使用正則表達式從字符串中提取羅馬數字(根據您在OP中鏈接的其他答案),然後使用此模塊將您的羅馬數字轉換爲數字。使用正則表達式(查找字符串)和該羅馬模塊的優點(將字符串轉換爲數字),並且您將擁有一個強大的解決方案。 – 2012-04-10 18:15:35