【问题标题】:Emoji Unicode in regular expression with variable number of groups具有可变组数的正则表达式中的表情符号 Unicode
【发布时间】:2014-03-05 04:21:04
【问题描述】:

我知道这是一个极端情况,但我遇到了一个使用正则表达式和可变组数的代码

根据docs,这是合法的:

捕获的与 a 关联的输入 组始终是 最近匹配的组。如果一个 第二次评估组 因为量化然后它 先前捕获的值(如果有), 如果第二个将被保留 评估失败。匹配字符串 "aba" 反对表达式 (a(b)?)+, 例如,将第二组设置为 “乙”。所有捕获的输入都被丢弃 在每场比赛开始时。

但是,当我尝试将其与 unicode 符号“带微笑的眼睛的笑脸”(U+1F601) 一起使用时,我得到了 StringIndexOutOfBoundsException。

这是根据规范预期还是存在错误?

这里是测试代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestEmoji {
    public static void main(String[] args)  {
        Pattern pattern = Pattern.compile("(A.)* EEE");

        testGroups(pattern, "ACAB EEE");
        testGroups(pattern,  "ABACA\uD83D\uDE01");

    }

    public static void testGroups(Pattern pattern, String s) {
        Matcher matcher = pattern.matcher(s);
        if (matcher.matches()) {
            System.out.println("matches");
            System.out.println(matcher.groupCount());
            for (int i = 1; i <= matcher.groupCount(); ++i) {
                System.out.println(matcher.group(i));
            }
        }
    }
}

还有例外:

matches
1
AB
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2
        at java.lang.String.charAt(String.java:658)
        at java.util.regex.Pattern$Slice.match(Pattern.java:3867)
        at java.util.regex.Pattern$GroupCurly.match0(Pattern.java:4382)
        at java.util.regex.Pattern$GroupCurly.match0(Pattern.java:4354)
        at java.util.regex.Pattern$GroupCurly.match(Pattern.java:4304)
        at java.util.regex.Matcher.match(Matcher.java:1221)
        at java.util.regex.Matcher.matches(Matcher.java:559)
        at TestEmoji.testGroups(TestEmoji.java:19)
        at TestEmoji.main(TestEmoji.java:12)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

【问题讨论】:

  • 您的正则表达式与ABACA\uD83D\uDE01 中的任何一个都不匹配,其中没有“EEE”。
  • @sln 它在比赛中崩溃

标签: java regex unicode


【解决方案1】:

在 Java Bugs 数据库中进行了一些挖掘后,我找到了它:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8007395

JDK-8007395:当输入字符串包含代理 UTF-16 字符时,Match.find() 中出现 StringIndexOutofBoundsException

【讨论】:

  • 在这种情况下,引擎应该在您打印“匹配”之前已经崩溃。为什么成功了?
  • 我明白了,它打印了第一个,然后引擎在第二个字符串匹配期间失败了。
  • 那么,解决方法是什么?如果引擎拒绝使用 UTF16 字符,您是否将字符串转换为 utf8? - 所以它在更新版本中得到了修复。
  • 在链接中查看问题描述: 3.当pattern与输入字符串不匹配时。解决方法:捕获异常并将其视为“假”返回值。
猜你喜欢
  • 2019-05-10
  • 2018-05-13
  • 2017-06-15
  • 2011-06-28
  • 2017-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
相关资源
最近更新 更多