我正试图编写一个正则表达式,将所有大写单词转换为小写,同时将大写罗马数字排除在外。
我找到的唯一方法是将所有后跟空格、逗号或句点的大写单词以及连字符单词转换为小写。然后将所有罗马数字转换回大写。
我用这个转换成小写:
(u+[ ,.-])
然后,我必须仔细查找并替换所有可疑的罗马数字。
有什么更好的方法可以做到这一点?我尝试过消极的前瞻性表达,但运气不好,但我写得不太好。
我测试的样本是美国宪法。以下是输入的示例:
我们,美国人民,为了形成一个更加完美的联合,建立正义,确保国内安宁,为共同防御,促进普遍福利,保障福祉为了我们自己和我们的子孙后代的自由,制定并建立美利坚合众国宪法。
文章I.
第。1.本协议授予的所有立法权应归属于美国国会,该国会由参议院和众议院组成。
第。2.众议院由全体人民每二年选出的成员组成几个州,每个州的选举人应众多分支机构的选举人所需的资格州议会。任何人不得作为代表还没有到二十五岁,已经七岁了年为美国公民,当选时不得,是他将被选中的州的居民。
文章IV.
文章诉
文章VI.
如果regex风格支持负外观,您可以尝试:
b(?![LXIVCDM]+b)([A-Z]+)b
它说"任何不完全由L、X、I、V、C、D、M组成的大写单词"(罗马数字)。
它还方便地阻止了单词"I"的转换。(顺便说一句,如果你想防止一个字母大写的单词被转换,请使用[A-Z]{2,}
——这将防止大写"a"(在句子开头)和I被转换,你通常希望保持它们的正常大小写)。
不过,这会阻止完全由这些字母组成的单词被匹配——我能想到的只有"DID",也许还有"DIV"(如HTML)、"DIM"(如维度)、"MID"、"MIDI"、"VIC"(在维多利亚?)。。。
尽管如此,您当然可以更改罗马数字regex,以更加考虑规则,例如
(?=[MDCLXVI])M{0,3}(C[DM]|DC{0,3}|C{1,3})?(X[LC]|LX{0,3}|X{1,3})?(I[XV]|VI{0,3}|I{1,3})?
说明:
(?=[MDCLXVI]) # make sure we match at least something
# (since everything in this regex is optional)
M{0,3} # Can have 0 to 3 Ms, being thousands
(C[DM]|DC{0,3}|C{1,3})? # for the hundreds column can have CD, CM,
# C, CC, CCC, D, DC, DCC, DCCC
(X[LC]|LX{0,3}|X{1,3})? # for the tens column can have XL, XC,
# L, LX, LXX, LXXX, X, XX, XXX
(I[XV]|VI{0,3}|I{1,3})? # for the ones column can have IX, IV,
# V, VI, VII, VIII, I, II, III.
我认为涵盖了所有可能的罗马数字。。。。
如果您的正则表达式风格不支持负面外观,也许您可以执行以下操作:
b((ROMAN_NUMERAL_REGEX)|([A-Z]+))b
并替换为"$2$3_converted_to_lower_case"(对不起,我不知道如何进行实际的转换)。
以上内容之所以有效,是因为正则表达式只与罗马数字正则表达式(捕获于$2)、或其他正则表达式(捕捉于$3)匹配。因此,2美元或3美元中的一个总是空的。