当输入字符串为 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 表示 a、b 或 c 3 次 但是整体匹配abc 为什么?
【问题讨论】:
听起来你想要的是正则表达式 (aaa)|(bbb)|(ccc) 它从给定列表中选择一个项目,并将该模式重复三遍。 @antlersoft:如果我是你,我会将我的评论复制到一个包含更多信息的答案中,这样你就可以获得接受的答案。 【参考方案1】:您正在寻找的模式是:
a3|b3|c3
您的模式意味着 - 匹配长度为 3
的字符串,其中包含任何字符 a
、b
或 c
。
此外,正如@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】:模式表示任意字符a
、b
或c
以任意顺序出现3 次。 abc
是与该模式匹配的字符串。
【讨论】:
以上是关于当输入字符串为 abccabaaaccbbbc 时,为啥 Java 正则表达式模式“[abc]3”与 abc 匹配的主要内容,如果未能解决你的问题,请参考以下文章