当输入字符串为 abccabaaaccbbbc 时,为啥 Java 正则表达式模式“[abc]3”与 abc 匹配

Posted

技术标签:

【中文标题】当输入字符串为 abccabaaaccbbbc 时,为啥 Java 正则表达式模式“[abc]3”与 abc 匹配【英文标题】:Why Java regex pattern "[abc]3" matches to abc when input string is abccabaaaccbbbc当输入字符串为 abccabaaaccbbbc 时,为什么 Java 正则表达式模式“[abc]3”与 abc 匹配 【发布时间】:2015-02-23 16:48:44 【问题描述】:

在http://docs.oracle.com/javase/tutorial/essential/regex/quant.html 关注 oracle 教程时。

找到如下命令行程序http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/regex/examples/RegexTestHarness.java输出:

输入您的正则表达式:[abc]3

输入要搜索的输入字符串:abccabaaaccbbbc

我发现文本“abc”从索引 0 开始到索引 3 结束。

我发现文本“cab”从索引 3 开始,到索引 6 结束。

我发现文本“aaa”从索引 6 开始,到索引 9 结束。

我发现文本“ccb”从索引 9 开始,到索引 12 结束。

我发现文本“bbc”从索引 12 开始,到索引 15 结束。

我的期望是模式 [abc]3 表示 abc 3 次 但是整体匹配abc 为什么?

【问题讨论】:

听起来你想要的是正则表达式 (aaa)|(bbb)|(ccc) 它从给定列表中选择一个项目,并将该模式​​重复三遍。 @antlersoft:如果我是你,我会将我的评论复制到一个包含更多信息的答案中,这样你就可以获得接受的答案。 【参考方案1】:

您正在寻找的模式是:

a3|b3|c3

您的模式意味着 - 匹配长度为 3 的字符串,其中包含任何字符 abc

此外,正如@Tim 在 cmets 中指出的那样,这可以简化为:

([abc])\1\1

([abc]) 匹配单个字符,并将其捕获到第 1 组中。然后\1\1 说,重复相同的字符两次。

【讨论】:

我更喜欢([abc])\1\1 - 更少重复。 aaa|bbb|ccc 甚至更好——它比原始表达式短了三个字符,并且它需要几乎零的正则表达式知识,这与具有两个反向引用的替代方案不同。【参考方案2】:

我认为您的期望(“a、b 或 c 三次”)是一旦匹配了一个字符(最初的 a),接下来的两个字符也必须是a,但要获得这种行为,您必须使用反向引用,例如([abc])\\12。相反,[abc]3 的意思就是 [abc][abc][abc]

(有更简单的编写方式,例如aaa|bbb|ccc,但我使用反向引用来遵循您的想法,即后来的匹配应该以某种方式反映较早的字符类匹配的内容。反向引用可以做到这一点。)

【讨论】:

【参考方案3】:

模式表示任意字符abc 以任意顺序出现3 次。 abc 是与该模式匹配的字符串。

【讨论】:

以上是关于当输入字符串为 abccabaaaccbbbc 时,为啥 Java 正则表达式模式“[abc]3”与 abc 匹配的主要内容,如果未能解决你的问题,请参考以下文章

c-string用户输入为空时如何发送错误消息?

当尝试在 adb shell 中输入问号时,它显示为 d,这是为啥呢?

CCF 201409-3 字符串匹配

CCF201409-3 字符串匹配

当搜索字符串为空时,带有连接的搜索查询显示所有行

CCF-CSP字符串匹配