比较两个字符串中的字符

时间:2011-10-24 17:49:04

标签: c# string string-comparison

在C#中,如何比较两个字符串中的字符 例如,假设我有这两个字符串
“bc3231dsc”和“bc3462dsc”

如何以编程方式找出字符串
两者都以“bc3”开头,以“dsc”结尾?

所以给定的是两个变量:

var1 = "bc3231dsc";  
var2 = "bc3462dsc";  

在比较var1和var2中的每个字符后,我希望输出为:

leftMatch = "bc3";  
center1 = "231";  
center2 = "462";  
rightMatch = "dsc";  

条件:
    1.字符串的长度始终为9个字符     2.字符串不区分大小写。

7 个答案:

答案 0 :(得分:4)

字符串类有两个可以使用的方法(StartsWith和Endwith)。

答案 1 :(得分:2)

在阅读了你的问题和已经给出的答案之后,我认为有一些约束缺失,这对你来说可能是显而易见的,但对社区来说却不是。但也许我们可以做一些猜测工作:

  1. 您将拥有一堆应该进行比较的字符串对。
  2. 每对中的两个字符串长度相同,或者只是通过比较从左到右同时读取的字符来感兴趣。
  3. 获取某种枚举,告诉我每个块的开始位置和持续时间。
  4. 由于事实,字符串只是字符的枚举,你可以在这里使用LINQ来了解匹配字符,如下所示:

    private IEnumerable<bool> CommonChars(string first, string second)
    {
        if (first == null)
            throw new ArgumentNullException("first");
    
        if (second == null)
            throw new ArgumentNullException("second");
    
        var charsToCompare = first.Zip(second, (LeftChar, RightChar) => new { LeftChar, RightChar });
        var matchingChars = charsToCompare.Select(pair => pair.LeftChar == pair.RightChar);
    
        return matchingChars;
    }
    

    有了这个,我们可以继续,现在找出这个方法的每个连续的真假标志块有多长:

    private IEnumerable<Tuple<int, int>> Pack(IEnumerable<bool> source)
    {
        if (source == null)
            throw new ArgumentNullException("source");
    
        using (var iterator = source.GetEnumerator())
        {
            if (!iterator.MoveNext())
            {
                yield break;
            }
    
            bool current = iterator.Current;
            int index = 0;
            int length = 1;
    
            while (iterator.MoveNext())
            {
                if(current != iterator.Current)
                {
                    yield return Tuple.Create(index, length);
                    index += length;
                    length = 0;
                }
    
                current = iterator.Current;
                length++;
            }
    
            yield return Tuple.Create(index, length);
        }
    }
    

    目前我不知道是否存在提供相同功能的已有LINQ功能。据我所知,应该可以使用SelectMany()(理论上你可以使用这种方法完成任何LINQ任务),但作为一种特殊实现,上面的内容更容易(对我而言)。

    然后可以使用以下方式使用这些函数:

    var firstString = "bc3231dsc";
    var secondString = "bc3462dsc";
    
    var commonChars = CommonChars(firstString, secondString);
    var packs = Pack(commonChars);
    
    foreach (var item in packs)
    {
        Console.WriteLine("Left side:  " + firstString.Substring(item.Item1, item.Item2));
        Console.WriteLine("Right side: " + secondString.Substring(item.Item1, item.Item2));
        Console.WriteLine();
    }
    

    然后你会给出这个输出:

    左侧:bc3    右侧:bc3

    左侧:231    右侧:462

    左侧:dsc    右侧:dsc

    最大的缺点是,Tuple的使用导致它导致丑陋的属性名称Item1Item2远离即时可读性。但是,如果它真的需要你可以引入你自己的简单类,持有两个整数,并有一些坚如磐石的属性名称。目前,关于每个块是否由两个字符串共享或者它们是否不同的信息也会丢失。但是再一次将这些信息也提供给元组或你自己的班级应该是相当简单的。

答案 2 :(得分:1)

    static void Main(string[] args)
    {
        string test1 = "bc3231dsc";
        string tes2 = "bc3462dsc";
        string firstmatch = GetMatch(test1, tes2, false);
        string lasttmatch = GetMatch(test1, tes2, true);
        string center1 = test1.Substring(firstmatch.Length, test1.Length -(firstmatch.Length + lasttmatch.Length)) ;
        string center2 = test2.Substring(firstmatch.Length, test1.Length -(firstmatch.Length + lasttmatch.Length)) ;

    }

    public static string GetMatch(string fist, string second, bool isReverse)
    {
        if (isReverse)
        {
            fist = ReverseString(fist);
            second = ReverseString(second);
        }
        StringBuilder builder = new StringBuilder();
        char[] ar1 = fist.ToArray();
        for (int i = 0; i < ar1.Length; i++)
        {
            if (fist.Length > i + 1 && ar1[i].Equals(second[i]))
            {
                builder.Append(ar1[i]);
            }
            else
            {
                break;
            }
        }
        if (isReverse)
        {
            return ReverseString(builder.ToString());
        }
        return builder.ToString();
    }

    public static string ReverseString(string s)
    {
        char[] arr = s.ToCharArray();
        Array.Reverse(arr);
        return new string(arr);
    }

答案 3 :(得分:0)

您需要的伪代码..

int stringpos = 0
string resultstart = ""
while not end of string (either of the two)
{
if string1.substr(stringpos) == string1.substr(stringpos) 
resultstart =resultstart + string1.substr(stringpos)
else
exit while
}

resultstart让你开始字符串..你可以做同样的事情......

答案 4 :(得分:0)

您可以使用的另一种解决方案是正则表达式。

Regex re = new Regex("^bc3.*?dsc$");
String first = "bc3231dsc";
if(re.IsMatch(first)) {
    //Act accordingly...
}

这使您在匹配时具有更大的灵活性。上面的模式匹配任何以bc3开头并以dsc结尾的字符串,除了换行符之外的任何字符串。通过改变。*?到\ d,您可以指定只需要两个字段之间的数字。从那里,可能性是无穷无尽的。

答案 5 :(得分:0)

using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

class Sample {
    static public void Main(){
        string s1 = "bc3231dsc";
        string s2 = "bc3462dsc";
        List<string> common_str = commonStrings(s1,s2);
        foreach ( var s in common_str)
            Console.WriteLine(s);
    }
    static public List<string> commonStrings(string s1, string s2){
        int len = s1.Length;
        char [] match_chars = new char[len];
        for(var i = 0; i < len ; ++i)
            match_chars[i] = (Char.ToLower(s1[i])==Char.ToLower(s2[i]))? '#' : '_';
        string pat = new String(match_chars);
        Regex regex = new Regex("(#+)", RegexOptions.Compiled);
        List<string> result = new List<string>();
        foreach (Match match in regex.Matches(pat))
            result.Add(s1.Substring(match.Index, match.Length));
        return result;
    }
}

答案 6 :(得分:0)

更新条件

using System;

class Sample {
    static public void Main(){
        string s1 = "bc3231dsc";
        string s2 = "bc3462dsc";
        int len = 9;//s1.Length;//cond.1)
        int l_pos = 0;
        int r_pos = len;
        for(int i=0;i<len && Char.ToLower(s1[i])==Char.ToLower(s2[i]);++i){
            ++l_pos;
        }
        for(int i=len-1;i>0 && Char.ToLower(s1[i])==Char.ToLower(s2[i]);--i){
            --r_pos;
        }
        string leftMatch = s1.Substring(0,l_pos);
        string center1 = s1.Substring(l_pos, r_pos - l_pos);
        string center2 = s2.Substring(l_pos, r_pos - l_pos);
        string rightMatch = s1.Substring(r_pos);
        Console.Write(
        "leftMatch = \"{0}\"\n" +
        "center1 = \"{1}\"\n" +
        "center2 = \"{2}\"\n" +
        "rightMatch = \"{3}\"\n",leftMatch, center1, center2, rightMatch);
    }
}