【问题标题】:Parsing unicode 'Vulgar Fractions' into double in Java在 Java 中将 unicode 'Vulgar Fractions' 解析为 double
【发布时间】:2014-11-19 12:24:29
【问题描述】:

我正在抓取网站的一些数据,其中部分数据包括 unicode 中的分数,例如6' 5¼"。我已成功使用正则表达式 (\\d)' (\\d{1,2}([\\xbc-\\xbe])?)\" 提取字符串的每个部分。

这给了我两个字符串,一个是"6",另一个是"5¼"

麻烦的部分是包含 unicode 粗俗分数的位。显然,使用Double.parseDouble 无法正确解析。

我到处寻找 Java 的示例,但找不到任何示例,我该如何将 ¼ 输出为 0.25?

如果它更容易,我可以再次拆分正则表达式,以便它单独返回小数部分,所以我得到三个字符串而不是两个。

【问题讨论】:

  • 可能将粗俗版本映射到它们的真实世界价值。
  • 我已经看到了该解决方案,但宁愿不将值硬编码,但如果归根结底是这样,那么我可能别无选择。
  • 第一次替换像s = s.replace("¼", ".25").replace("½", ".5")-replace("¾", ".75");怎么样?
  • 差不多。 ¼ 可能对我们人类有意义,但对于计算机来说,它和大多数其他角色一样,与 aP 没有什么不同
  • would rather not have the values hard coded in 硬编码有多少?如果它们在字符代码中是连续的,您可以先对字符进行边界检查,然后进行一些数学运算,例如匹配字符的代码减去基本字符的代码乘以转换,然后转换为字符串。

标签: java regex unicode double


【解决方案1】:

[I...] 宁愿没有硬编码的值

您认为 ¼ 的含义会改变吗?我会使用枚举“硬编码”这些值:

enum VulgarFraction {
    ...,
    ONE_QUARTER('¼', 0.25),
    ONE_HALF('½', 0.5),
    ...
    ;

    private final char codepoint;
    private final double value;

    VulgarFraction(char codepoint, double value) {
         this.codepoint = codepoint;
         this.value = value;
    }

    char getCodepoint() { return codepoint; }

    double getValue() { return value; }
}

【讨论】:

    【解决方案2】:

    有一种方法可以做到这一点,而无需您自己的粗俗分数表,您可以使用内置在 Unicode 数据中的表。

    如果您转换为 Unicode 规范化形式 KD,它会将分数分解为由纯数字包围的分数斜线 (U+2044)。所以你可以这样做:

    String[] fraction = Normalizer.normalize("¼", Normalizer.Form.NFKD).split("\u2044");
    if (fraction.length == 2) {
        double value = (double) Integer.parseInt(fraction[0]) / Integer.parseInt(fraction[1]);
    }
    

    分数字符比 U+00BC–U+00BE 范围内的字符多,例如 ⅛,因此如果您想避免对该范围进行硬编码,我建议将其正则表达式更改为类似 @ 987654322@.

    【讨论】:

    • 希望我能给出这个答案,而不仅仅是 +1。我现在正在处理的应用程序中需要 java.text.Normalizer,但我不知道!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    相关资源
    最近更新 更多