2011-08-18 157 views
4

我的正则表达式匹配罗马数字

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

我用它来检测是否存在任何文字的罗马数字。

eregi("(IX|IV|V?I{0,3}[\.]| M{1,4}[\.]| CM|CD|D?C{1,3}[\.]| XC|XL|L?X{1,3}[\.])", $title, $regs) 

但罗马数字的格式始终是这样的:“四” ......我在eregi例如空格加号之前和“”数字后,但我仍然得到相同的结果。如果文本是像“somethinvianyyhing”的结果将是六(两者之间)...

我做错了什么?

回答

2

您在VI之前没有空间,该空间在写入前始终属于替代方法,而不是全部。 \.也一样,它总是属于它的写法。

试试这个

" (IX|IV|V?I{0,3}|M{1,4}|CM|CD|D?C{1,3}|XC|XL|L?X{1,3})\." 

看到它here on Regexr

这将匹配


II。三,四,
V.
六, VII。 VIII。九,

但不是

XI。 MMI。 MMXI。
somethinvianyyhing

你的方法来匹配罗马数字还远不是正确,匹配罗马数字更正确的做法是这样的,换号至50(L)

^(?:XL|L|L?(?:IX|X{1,3}|X{0,3}(?:IX|IV|V|V?I{1,3})))$ 

看到它here on Regexr

我只在表面测试过这个,但是你会发现这样会变得非常复杂,在这个表达式中,C,D和M仍然会丢失。

不要说特殊情况,例如4 = IV = IIII,其中有更多。

Wikipedia about Roman numbers

+0

同样在SO:http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression – kapa

+0

我纠正我的解决方案和Regexr链接。 – stema

+2

有一个Perl模块可以正确处理罗马数字。知道你有一个方法是先*匹配'/ \ b([ivxldcm] +)\ b/i'然后*然后*检查'Roman :: isroman($ 1)'是否返回true。否则你会得到错误的答案。它只能用于ASCII,这意味着它只能达到4000.最长的这种合法字符串是'MMMDCCCLXXXVIII'。使用Unicode,你可以高得多,因为你有更大的罗马数字,例如ↂ为10,000 *&c *,而且你也可以使用macron或overline来获得1000倍的基本字符。我有一个模块可以处理所有这些,但它当然是用Perl编写的 – tchrist