
本文介绍如何使用 ICU4J 的 RuleBasedNumberFormat 正确将英文序数词字符串(如 "FOURTH"、"TWENTY-FIRST")解析为对应整数值,重点说明为何 ORDINAL 模式不支持解析、应改用 SPELLOUT 模式,并强调大小写敏感性等关键细节。
本文介绍如何使用 icu4j 的 `rulebasednumberformat` 正确将英文序数词字符串(如 "fourth"、"twenty-first")解析为对应整数值,重点说明为何 `ordinal` 模式不支持解析、应改用 `spellout` 模式,并强调大小写敏感性等关键细节。
ICU4J 的 RuleBasedNumberFormat 并不支持直接通过 ORDINAL 模式反向解析序数词字符串(如 "FOURTH" → 4)。其 ORDINAL 模式仅用于格式化(即整数转序数字符串,如 4 → "4th"),而解析功能仅在 SPELLOUT 模式下可用——该模式专为拼写数字(如 "four", "twenty-first")设计,且隐式兼容标准英文序数词拼写形式(如 "fourth"、"twenty-first"),但要求输入为小写。
正确做法是:
- 使用 RuleBasedNumberFormat.SPELLOUT 构造格式器;
- 将待解析字符串统一转为小写(推荐使用 String.toLowerCase(Locale.ROOT),避免区域设置导致的意外字符映射);
- 调用 parse() 方法并捕获 ParseException;
- 对返回的 Number 对象调用 intValue() 获取结果。
以下是完整、健壮的示例代码:
import com.ibm.icu.text.RuleBasedNumberFormat;
import com.ibm.icu.text.ParseException;
public class OrdinalParser {
public static int parseOrdinalString(String ordinalStr, Locale locale) throws ParseException {
if (ordinalStr == null || ordinalStr.trim().isEmpty()) {
throw new IllegalArgumentException("Input string cannot be null or empty");
}
RuleBasedNumberFormat formatter = new RuleBasedNumberFormat(locale, RuleBasedNumberFormat.SPELLOUT);
// 必须转小写:SPELLOUT 解析器仅识别小写形式
String normalized = ordinalStr.trim().toLowerCase(Locale.ROOT);
Number result = formatter.parse(normalized);
return result.intValue();
}
public static void main(String[] args) {
try {
System.out.println(parseOrdinalString("FOURTH", Locale.US)); // 输出: 4
System.out.println(parseOrdinalString("twenty-first", Locale.US)); // 输出: 21
System.out.println(parseOrdinalString("ONE HUNDREDTH", Locale.US)); // 输出: 100
} catch (ParseException e) {
System.err.println("Failed to parse ordinal string: " + e.getMessage());
}
}
}
⚠️ 注意事项:
- 大小写敏感:parse() 严格匹配小写形式,"FOURTH" 或 "Fourth" 均会解析失败,务必调用 .toLowerCase(Locale.ROOT);
- 空格与连字符:支持常见格式(如 "twenty first"、"twenty-first"、"one hundredth"),但建议保持原始规范拼写;
- Locale 一致性:确保 Locale 与字符串语言一致(如英文序数词必须用 Locale.US 或 Locale.ENGLISH);
- 异常处理:parse() 在无法识别时抛出 ParseException,不可忽略;
- 性能提示:若需高频解析,可复用 RuleBasedNumberFormat 实例(线程安全,但非完全无状态,建议每个线程持有独立实例或加锁)。
综上,RuleBasedNumberFormat.SPELLOUT 是 ICU4J 中解析英文序数词字符串的唯一可靠方式。理解其设计意图(拼写数字解析 ≠ 序数格式化)并遵循标准化预处理流程,即可稳定实现 "FOURTH" → 4 等转换需求。










