罗马数字的正则表达式不起作用

2024-10-03 17:27:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用以下正则表达式从文本中识别罗马数字:

>>>Title="LXXXIV XC, XCII      XXX     LXII"
>>>RomanNum = re.findall(r'[\s,]+M{0,4}[CM|CD|D?C{0,3}]?[XC|XL|L?X{0,3}]?[IX|IV|V?I{0,3}]?[\s,]+', Title, re.M|re.I)`
>>>RomanNum
[' \t']

我想要这样的东西:

['LXXXIV', 'XC, 'XCII', 'XXX', 'LXII']

就我对正则表达式的理解而言,我认为至少应该匹配XCXC应该将上面正则表达式的[XC|XL|L?X{0,3}]部分与前面的空白和后面的逗号相匹配,由上面的正则表达式捕获。我错过了什么?你知道吗

除此之外,我还可以实现以下预期结果(但我希望避免更大的复杂性):

>>>RomanNum = [re.search(r'^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$', TitleElem, re.M|re.I) for TitleElem in re.split(',| ', Title)]`

谢谢你的帮助。你知道吗


Tags: retitlecdcmxxxixxcxl
3条回答

Dive Into Python提供了一个很好的正则表达式来检测罗马数字。它们还提供了一个sample script,您可以利用它来启动。这个脚本来自我的第一个链接的7.5部分。你知道吗

#Define pattern to detect valid Roman numerals
romanNumeralPattern = re.compile("""
    ^                   # beginning of string
    M{0,4}              # thousands - 0 to 4 M's
    (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                        #            or 500-800 (D, followed by 0 to 3 C's)
    (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                        #        or 50-80 (L, followed by 0 to 3 X's)
    (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                        #        or 5-8 (V, followed by 0 to 3 I's)
    $                   # end of string
    """ ,re.VERBOSE)

如果要使用findallfinditer方法在字符串中查找多个罗马数字,一种可能的模式是:

(?=[MDCXLVI])(?<![MDCXLVI])M{0,4}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})(?![MDCXLVI])

它有点长,我会解释为什么我认为它是有效的:

(?=[MDCXLVI])是一个lookahead,它检查位置后面是否跟有这些字符之一。此前瞻有两个功能:

  • 第一种是模拟一种第一字符识别,以快速避免所有不包含这些字符的位置(这样,regex引擎就不需要用M{0,4}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})测试所有可能的开头)。

  • 第二个检查是否至少有一个字符,因为M{0,4}(?:C[MD]|D?C{0,3})(?:X[CL]|L?X{0,3})(?:I[XV]|V?I{0,3})可以匹配空字符串。

(?<![MDCXVLI])(?![MDCXVLI])被用作边界,以确保周围没有其他“罗马字符”(否则像ILVIII这样的子字符串将返回LVIII,而不是跳过格式错误的整个字符组)。注意,其他类型的边界也是可能的,比如\b(?<![^\s,])(?![^\s,])。。。取决于字符串格式。还要注意,左边界只放在(?=[MDCXVLI])之后,这样就不会破坏第一个字符的区分。你知道吗

CM|CD这样的交替被减少到C[MD]。你知道吗

该模式仅使用非捕获组(?:...)来保留内存并避免未使用的存储任务。你知道吗

此时您的正则表达式语法已关闭:

XC should match [XC|XL|L?X{0,3}]

因为您使用了方括号来描述圆括号的行为。将方括号改为圆括号以进行更正。你知道吗

这个错误在完整正则表达式的其他部分重复出现。你知道吗

相关问题 更多 >