我有一个名字列表:
Joe
Bob
Carl
Seth Smith II
Doug IV
我正在尝试编写一个正则表达式,该表达式将返回名称,但不返回罗马数字。所以我的结果集应该像这样:
Joe
Bob
Carl
Seth Smith
Doug
我一直在看消极的展望,但是对此还很陌生,所以我不确定自己是否走对了。谢谢!
答案 0 :(得分:1)
^(?:.(?! (?=[MDCLXVI])(M*)(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$))+\S?
此正则表达式应该起作用,但是对于您的用例来说可能有点过头了,因为它会按照现代的严格符号检查所有可能的罗马数字,包括成千上万个非常大的数字。它会正确处理符合罗马数字语法的大写字母名称或姓氏,除非它们出现在最后(例如“ Jet LI”),在这种情况下,它们将被处理为罗马数字。
这是我的逻辑:
<any character not followed by space + roman numeral + end>
实例以及可能的一个或多个非空格字符(姓氏的最后一个字母,后跟 后跟空格+罗马数字+结束)。
^(?:<any non-linebreak character not followed by space + Roman numeral + end>)+\S?
<any non-linebreak character not followed by space + Roman numeral + end>
使用此正则表达式进行匹配:
.(?! <Roman numeral>$)
<Roman numeral>
可以这样匹配:
(?=[MDCLXVI])(M*)(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})
注意:
如果您只想考虑某个范围内的罗马数字,请相应地更新<Roman numeral>
部分。例如。小于20的数字将变为(?=[XVI])X?(I[XV]|V?I{0,3})
。整个正则表达式将是:
^(?:.(?! (?=[XVI])X?(I[XV]|V?I{0,3})$))+\S?
这是另一种可能的正则表达式,它应该比上面的正则表达式快,因为它会贪婪地匹配所有非空格,并且仅在出现空格的情况下才检查否定的超前查找。
^(?:\S+| (?!(?=[IVXLCDM])(M*)(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$))+
这里的一般逻辑是:
^(?:\S+| (?!<Roman numeral>$))+