正则表达式连续两次匹配包含一个字符的单词
问题
正如标题所说,我的目标是发现,当且仅当它包含的子串词相匹配的正则表达式究竟这是不是由相同的字符包围两个连续的字符。
测试用例
Helo-->falseprogramming-->truebelllike-->false(因为有三个l)shellless-->true(即使有三个ls,这个输入也应该匹配,因为有两个ss
我以前尝试过的事情
正则表达式[a-zA-Z]*([a-zA-Z])1[a-zA-Z]*匹配至少有两个连续字符的单词,但belllike仍会匹配,因为连续字符没有上限。
我还尝试使用负前瞻和后视。对于一封信,这可能如下所示:
[a-zA-Z]*(?<!a)aa(?!a)[a-zA-Z]*
这个正则表达式满足了这封信的所有要求,a但我和我问的人都不能将它概括为使用捕获组,因此适用于任何信件(复制粘贴此语句 26 次 - 每个字母一次 - 并将它们与 OR 组合不是我正在寻找的解决方案,即使它可能会奏效)。
我在找什么
当然,所描述问题的解决方案会很棒。如果它不能用正则表达式完成,我会同样高兴地解释为什么这是不可能的。
背景
这项任务是我必须为大学完成的任务的一部分。在一次对话中,教授后来表示他们实际上并不想问这个问题,并且可以接受三个或更多相同字符的字符序列。然而,试图为这个问题寻找解决方案的努力激发了我对正则表达式是否真的可以实现的兴趣,如果可以,如何实现。
要使用的正则表达式风味
即使最初的任务应该在 Java 8+ regex 风格中完成,我会用任何 regex 风格的解决方案来解决所描述的问题。
回答
你可以试试:
^(?:.*?(.)(?!1))?(.)2(?!2).*$
查看演示
^- 起点线锚。(?:- 打开非捕获组:.*?- 除换行符(懒惰)之外的 0+ 个字符;(.)(?!1)- 除换行符之外的单个字符的第一个捕获组,但使用负前瞻来断言它后面没有相同的字符,并持有对该字符的反向引用。)?- 关闭非捕获组并使其可选。
(.)2(?!2)- 与之前相同的构造,但这次不同的是,在第二个捕获组和用于断言位置的负前瞻之间存在反向引用,后跟完全相同的字符。.*- 除换行符(贪婪)之外的 0+ 个字符;$- 结束线锚。
对此的可视化: