查找字符串中的每个非唯一字符

时间:2017-10-16 10:02:16

标签: regex

在这里遇到一些难题。我想要做的是创建一个正则表达式,实际上将为一个字符串返回6个匹配项:

abbccddeeffa

那里有6个独特的角色,都出现了两次。但是,无论我尝试什么,我似乎无法通过正则表达式实现这一目标。

(.).*\1

将返回1

所以,我认为贪婪是那里的问题。

(.).*?\1 

仍然1.好吧,先来看一下呢?

(.).*?(?=\1)

仍然是1。

同时使用https://regexr.com/https://regex101.com/进行实验和测试。

用例与我的个人书面密码管理器中的密码强度指示器相关联。

我喜欢正则表达式,它会告诉我密码中有多少字符,例如

W&安培;!Nw8uD(TA * ^ T6t0n3%l9.ln1Wo._U

出现不止一次。在这种情况下的答案是5: W w T n l

2 个答案:

答案 0 :(得分:4)

我会在答案的顶部添加一个基于代码的解决方案,因为你在评论中提到了C#,因为它似乎是最简单的C#方法来获取字符串中的所有重复字符(基于this answer ):

             <script language="javascript" type="text/javascript">
    function CallPrint(strid) {
        var prtContent = document.getElementById(strid);
        var WinPrint = window.open('', '', 'letf=0,top=0,width=1200,height=800,toolbar=0,scrollbars=0,status=0,dir=ltr');
        WinPrint.document.write(prtContent.innerHTML);
        WinPrint.document.close();
        WinPrint.focus();
        WinPrint.print();
        WinPrint.close();
        prtContent.innerHTML = strOldOne;
    }
</script>

请参阅the C# demo

此处,using System; using System.Collections.Generic; using System.Linq; public class Test { public static void Main() { var s = "abbccddeeffa"; var repeatedChars = s.GroupBy(x => x).Where(y => y.Count() > 1).Select(z=>z.Key); Console.Write(string.Join(", ", repeatedChars)); } } // => a, b, c, d, e, f 对字符进行分组(.GroupBy(x => x)string的数组),并将相同的字符存储在一个char下。我们使用Key得到每个组的出现次数,而y.Count()只会获取出现次数超过1次的组。 .Where(y => y.Count() > 1)将返回前一个表达式返回的组的字符。

如果您正在寻找一些正则表达式方法,您可以在.Select(z=>z.Key)之后使用前瞻部件:

(.)

请参阅the regex demo

模式匹配并使用(.)(?=.*\1) ^^^^^^^^ 将char捕获到组1中,(.)将仅断言(但不消耗,即不会将匹配的字符添加到匹配值,并且不会提前正则表达式索引)除了当前位置左边的换行符之外的任何0+字符之后有相同的字符。

(?=.*\1)模式未返回预期结果,因为(.).*?(?=\1)部分仍然正在消耗,正则表达式引擎无法“重新匹配”已经“属于”的部分“到有效匹配(.*?的第一个匹配为abbccddeeffa,然后只有abbccddeeff仍然无法与此模式匹配。)

如果您不知道预期的输入类型,那么在looahead中使用a.*?是不太重要的:如果重复的char关闭,.*会更有效如果重复的字符看起来更靠近字符串的末尾,那么对于捕获的字符.*?会更好。

答案 1 :(得分:0)

public static void FindNonUnique( string searchTerm )
{
    var s = abbccddeeffa;
    var uniqueString = "";
    var uniqueMap = new Dictionary<char,int>();

    foreach( var letter in s )
    {
        if ( uniqueMap.ContainsKey( letter ) == false )
            uniqueMap.Add( letter , 1 );
        else
        {
            if ( uniqueMap[letter] == 1 )
            {
                uniqueString += letter;
                uniqueMap[letter]++;
            }
        }
    }

    Console.WriteLine( uniqueString );
}