【问题标题】:Handling unicode symbols in Java regex在 Java 正则表达式中处理 unicode 符号
【发布时间】:2017-01-21 12:05:57
【问题描述】:

我的任务是从带有数字和一些文本的字符串中解析整数值。数字可以使用不同的语言环境进行格式化:

15 000 km
15,000 km
15.000 km

我有一个解决方案:

(\d+[[\s\.,]?\d+]*)

适用于上述示例。 但作为一个边缘情况,有一个特殊的输入机智代码 160 而不是常规空间(代码 32):

15 000 km

如何在java中使用正则表达式来解决这个问题?

拨弄一下:http://java-regex-tester.appspot.com/regex/5d8dd002-fe68-40c3-bf82-42e8574a2f5c

理想情况下,我想要一个适用于任何不可打印字符的通用解决方案。

【问题讨论】:

  • ASCII 码 160 是带有重音符号的 a。不知道你是怎么收到的。
  • 你知道解析输入时的语言环境吗?如果是,您可以使用不同的方法而不是包罗万象的正则表达式。例如,您可以使用策略模式并为该语言环境使用特定语法的解析器
  • 如果您有硬空格,请确保您使用的是支持 Unicode 的 \s。请参阅ideone.com/jrligF,其中\s 使用时没有Pattern.UNICODE_CHARACTER_CLASS 标志。
  • (\d+[\s.,\xA0]?\d+)这样简单的东西怎么样
  • ideone.com/jKXQy2 使用(\d+[\s.,\xA0]?\d+)

标签: java regex parsing regex-greedy


【解决方案1】:

为什么不包括额外的分隔符 (\u00a0)?

(\d+(?:[\s.,\u00a0]?\d+)*)

使用UNICODE_CHARACTER_CLASS 标志编译将使\s 匹配,但有一个警告,它可能会更慢;您必须进行测试,看看它是否对您的输入很重要。

【讨论】:

    【解决方案2】:

    您可以使用Pattern.UNICODE_CHARACTER_CLASS 标志来让您的\s 识别Unicode:

    String pattern = "(?U)\\d+[\\s.,]?\\d+";
                      ^^^
    

    Java demo:

    String value1 = "15 000 km\n15,000 km\n15.000 km\n15 000 km";
    String pattern1 = "(?U)\\d+[\\s.,]?\\d+";
    Pattern ptrn = Pattern.compile(pattern1);
    Matcher matcher = ptrn.matcher(value1);
    while (matcher.find())
        System.out.println(matcher.group(0));
    

    输出:

    15 000
    15,000
    15.000
    15 000
    

    【讨论】:

      【解决方案3】:

      您可以使用这个简单的正则表达式来匹配由 0 或多个非数字分隔的任意 2 个数字,即\D

      \d+\D*\d+
      

      在 Java 中:

      String regex = "\\d+\\D*\\d+";
      

      \D 将匹配任何非数字,包括任何 unicode 字符。

      Your Updated Demo

      【讨论】:

      • 我想过这种解决方案,但这不适用于:15km 15 km 15 000 000 km
      猜你喜欢
      • 2011-07-03
      • 1970-01-01
      • 2019-05-10
      • 2018-04-05
      • 2013-03-02
      • 2017-01-24
      • 2012-03-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多