什么是用于查找字符串中第一个非连续重复字符的Perl正则表达式?

时间:2010-03-30 21:13:32

标签: regex perl

你的任务,如果你选择接受它,就是编写一个Perl正则表达式,对于给定的字符串,它将返回第一次出现的不连续重复的字符。换句话说,两个字符前面和后面都有与自身不同的字符(或字符串的开头/结尾)。

示例:

IN: aabbcdecc
OUT: c

请注意,“不连续重复”并不意味着“字符串中的任何地方”。

注意:它必须是纯正则表达式。例如。显而易见的解决方案(克隆字符串,删除所有重复项,并打印第一个剩余字符)不算数,虽然它解决了问题。

这个问题的灵感来自于我对此有点偏离主题的答案:How can I find the first non-repeating character in a string using Perl?

3 个答案:

答案 0 :(得分:2)

(?:(.)\1+)*(.?)

获得第二次捕获。 (如果连续复制每个字符,将返回一个空字符串。)

测试用例:

~:2434$ perl -e "\"abc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
a
~:2435$ perl -e "\"aabbcc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"

~:2436$ perl -e "\"aabbc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
c
~:2437$ perl -e "\"aabcc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
b
~:2438$ perl -e "\"aabcbbbcccccc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
b
~:2439$ perl -e "\"aabbvbbcccccc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
v
~:2440$ perl -e "\"aabbcdecc\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
c
~:2441$ perl -e "\"aabbccddeef\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
f
~:2442$ perl -e "\"faabbccddeef\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
f
~:2443$ perl -e "\"faabbccddeefax\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
f
~:2444$ perl -e "\"xfaabbccddeefx\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
x
~:2445$ perl -e "\"xabcdefghai\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
x
~:2446$ perl -e "\"cccdddeeea12345\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
a
~:2447$ perl -e "\"1234a5678a23\" =~ m/(?:(.)\1+)*(.?)/; print \$2;"
1

或(如果每个字符连续重复,则不匹配。)

(?:^|(.)(?!\1))(.)(?!\2)

答案 1 :(得分:1)

use 5.010;
$str=~/^(([a-z])\g{-1}+)*(?<c>[a-z])/i;
$char = $+{c};

答案 2 :(得分:0)

我希望Perl有一个正则表达式否定标志!即返回所有不匹配的字符/ regex /

您正在寻找的是真正的正则表达式捕获补充:

m/(.)(\1)+/

我在本页面上针对Brian的数据列表(他的程序列表中的结果)尝试了所有建议。没有完全的工作。

正则表达式:

(?:^|(.)(?!\1))(.)(?!\2) 

无法匹配第2行和第3行中的开头'f'.Brian's与第2行和第3行开头的'f'或第5行末尾的任何单身人士不匹配。

正则表达式:

$str=~/^(([a-z])\g{-1}+)*(?<c>[a-z])/i;
$char = $+{c};

确实有效。

我发现的唯一一个正则表达式是一个简单的:

#!/usr/bin/perl
while( <DATA> ) {
    chomp;
    print "BEFORE: $_\n";
    s/(.)(\1)+//g;
    print "AFTER: $_\n";
    print "charater: " . substr($_,0,1) . "\n\n";
 }
__END__
aabbccddeef
faabbccddeef
faabbccddeefax
xfaabbccddeefx
xabcdefghai
cccdddeeea12345
1234a5678a23
aabbcdecc
abcdefg
aabbccddeef
cccdddeeea12345

这适用于“给第一个角色”这个简单的例子。 ((编辑:重读:对不起,我现在读到明显删除双打并不是你想要的......)

喜欢听到是否有更好的解决方案。