Regex 查找具有重复字符的单词

Regex 查找具有重复字符的单词,regex,perl,Regex,Perl,要在字典中的每个单词的第二个和最后一个位置精确搜索具有相同字符的单词,并在中间某个位置搜索一次 示例: statement - has the "t" at the second, fourth and last place severe = has "e" at 2,4,last abbxb = "b" at 2,3,last 错 我的grep坏了 my @ok = grep { /^(.)(.)[^\2]+(\2)[^\2]+(\2)$/ } @wordlist; e、 g.会议 per

要在字典中的每个单词的第二个和最后一个位置精确搜索具有相同字符的单词,并在中间某个位置搜索一次

示例:

statement - has the "t" at the second, fourth and last place
severe = has "e" at 2,4,last
abbxb = "b" at 2,3,last

我的grep坏了

my @ok = grep { /^(.)(.)[^\2]+(\2)[^\2]+(\2)$/ } @wordlist;
e、 g.会议

perl -nle 'print if /^(.)(.)[^\2]+(\2)[^\2]+(\2)$/' < /usr/share/dict/words
怎么了

正确的正则表达式应该是什么

编辑:

如何捕获封闭的组?e、 g.对于

statement - want cantupre: st(a)t(emen)t - for the later use

my $w1 = $1; my w2 = $2; or something like...

这是适用于您的正则表达式:

^.(.)(?=(?:.*?\1){2})(?!(?:.*?\1){3}).*?\1$
现场演示:使用前瞻:

/^.(.)(?!(?:.*\1){3}).*\1(.*)\1$/
意思是:

/^.(.)(?!(?:.*\1){3})  # capture the second character if it is not
                       # repeated more than twice after the 2nd position
.*\1(.*)\1$              # match captured char 2 times the last one at the end
(?:(?!STRING)。*
字符串
,而
[^CHAR]*
字符
,因此您需要的是:

^.#忽略第一个字符
()#捕获第二个字符
(?:(?!\1)。*#不是第二个字符的任何字符数
\1#秒字符
(?:(?!\1)。*#不是第二个字符的任何字符数
\字符串末尾的1\z#第二个字符。
所以你得到:

perl -ne'print if /^. (.) (?:(?!\1).)* \1 (?:(?!\1).)* \1$/x' \
   /usr/share/dict/words

要捕获两者之间的内容,请在两个
(?:(?!\1)周围添加paren.*


[^\2]
不符合您的想法,字符是字符类括号内的文字。
\2
不完全是文字,
\2
表示一个chr(2)a.k.a.Ctrl BIs这是正确的还是错误的:
xxxix
?此正则表达式使用正反两种外观。这只是意味着第二个字符后面应该紧跟着两个相似的字符,而不是三个或更多的字符。这是这个技巧的扩展,允许
/foo/&&&/bar/
被写成
/^(?=.*foo)(?=.*bar)/
。请添加一个子问题。因为我不知道将捕获的
()
放在哪里,以便对封闭的字符串进行caturing。您能帮忙吗?使用
(.*?)\1(.*?\1
而不是
(?:.*?\1){2}
来捕获字符之间的字符串。或者使用我更直接的解决方案:)@ikegami谢谢-很遗憾我不能接受你的答案,OP已经接受了这个答案要捕获两者之间的内容,请在两个
(?:(?!\1)周围添加paren.*
。(更新)有趣的方法,但请去掉那些
{1}
伪量词。他们所做的就是把正则表达式弄得乱七八糟。
/^.(.)(?!(?:.*\1){3})  # capture the second character if it is not
                       # repeated more than twice after the 2nd position
.*\1(.*)\1$              # match captured char 2 times the last one at the end
perl -ne'print if /^. (.) (?:(?!\1).)* \1 (?:(?!\1).)* \1$/x' \
   /usr/share/dict/words
perl -nle'print "$2:$3" if /^. (.) ((?:(?!\1).)*) \1 ((?:(?!\1).)*) \1\z/x' \
   /usr/share/dict/words
my @ok = grep {/^.(\w)/; /^.$1[^$1]*?$1[^$1]*$1$/ } @wordlist;