【问题标题】:Strange behavior of String's matches() methodString的matches()方法的奇怪行为
【发布时间】:2011-10-05 16:20:47
【问题描述】:

我遇到了一个关于 String 的 matches(RegExp) 方法的有趣问题。

assertTrue("33CCFF".matches("[0-9A-Za-z]{6}"));
assertTrue("CC33FF".matches("[0-9A-Za-z]{6}"));
assertTrue("CC3355".matches("[0-9A-Za-z]{6}"));
assertTrue("CC9955".matches("[0-9A-Za-z]{6}"));
assertTrue("CC3366".matches("[0-9A-Za-z]{6}"));
assertTrue("CC3965".matches("[0-9A-Za-z]{6}"));
assertTrue("CC1961".matches("[0-9A-Za-z]{6}"));
assertTrue("CC9999".matches("[0-9A-Za-z]{6}"));
assertTrue("СС3966".matches("[0-9A-Za-z]{6}")); // failing
assertTrue("СС9965".matches("[0-9A-Za-z]{6}")); // failing
assertTrue("СС9966".matches("[0-9A-Za-z]{6}")); // failing

最后 3 个断言意外失败。我找不到发生这种奇怪行为的任何原因。你有同样的问题吗?你有什么想法吗?

顺便问一下,我的java版本如下。

java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)

【问题讨论】:

  • 我在您的回答后进行了调查,发现高位 C 字符 (+) 与低位 C 字符 (С) 不同。最后 3 行中的 C 字符似乎来自西里尔字母。 webdesign.about.com/od/localization/l/blhtmlcodes-ru.htm
  • 问题是由于用户输入造成的。要检查输入是否为 alpha-decimal(即使对于 Cyrillic C),org.apache.commons.lang.StringUtils.isAlphanumeric() 将返回 true,如下所示:assertTrue(StringUtils.isAlphanumeric("\u0421\u0421")) ; // 西里尔 C assertTrue(StringUtils.isAlphanumeric("\u00E7\u00E7")); // ascii C

标签: java regex string


【解决方案1】:

最后三个实际上不以 ASCII“C”字符开头。它们以 看起来 像“C”的非 ASCII 字符开头。这与 [0-9A-Za-z] 集合中的任何内容都不匹配,因此模式失败。

(我通过将代码复制并粘贴到文本编辑器中发现了这一点,该编辑器不能很好地处理非 ASCII 字符 - 它们显示为“?”。)

【讨论】:

  • 对,错误 C 字符的 HEX 代码是 0x3F,但之前的所有 C0x43
  • @sll: 不,3F 只是“?”它通常用于表示无法以其他方式表示的字符。显示的字符是不是“?”。
  • 好收获!看起来我的编辑在保存之前用? 替换了这个字符
  • @JonSkeet 确实不错。我现在知道了。非常感谢!
【解决方案2】:

您的“СС3966”(我正在剪切和粘贴)被标记为非 UTF-8,这就是 reg-ex 不匹配它们的原因。当我更改您的文本并自己输入时,它会按预期工作。不确定您从哪里复制这些值,但这是您的问题

【讨论】:

  • 我明白你的意思。您以 JonSkeet 的身份发现了这个问题。非常感谢您的回答。
  • 这很有趣...约翰和我发现了相同的答案,我比他早 1 分钟找到了答案...他得到了 12 个赞,我得到了 1 个 :) 看起来这是一场人气竞赛毕竟!大声笑。
  • 顺便说一句,当我将您的匹配项粘贴到我的 Eclipse 中并尝试保存时,它会弹出一个对话框,说我正在尝试保存非 UTF-8 文本。我认为我根本没有修改我的 eclipse 设置,所以你应该明白为什么你的设置没有对未来的此类问题发出相同的警告。
  • 感谢您的建议。我会检查的。
猜你喜欢
  • 1970-01-01
  • 2015-12-01
  • 2021-09-23
  • 1970-01-01
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多