C#String Comparison等于false

Ada*_*Hey 7 .net c# string-comparison

我有一个字符串比较问题 - 在大多数情况下 - 表现得如预期的那样,但是由于我的代码没有将字符串对检测为重复,因此留下了大量重复数据库插入.

我以为我把它缩小到一个文化问题(西里尔字符),我解决了,但我现在得到'假阴性'(两个显然相等的字符串显示为不相等).

我查看了以下类似的问题,并尝试了以下比较方法.

我检查的类似SO问题:

以下是比较字符串的示例:(标题和说明)

饲料标题:埃尔斯伯格:他是英雄

饲料设计:丹尼尔埃尔斯伯格告诉美国有线电视新闻网的唐柠檬,国家安全局的骗子爱德华斯诺登表现出了勇气,做了大量的服务.

db title: Ellsberg:他是英雄

db desc:丹尼尔埃尔斯伯格告诉美国有线电视新闻网的唐柠檬,国家安全局的骗子爱德华斯诺登表现出勇气,做了大量的服务.

我的应用程序将从RSS提要获取的值与我在数据库中提供的值进行比较,并且只应插入"新"值.

//fetch existing articles from DB for the current feed:
    List<Article> thisFeedArticles = (from ar in entities.Items
                                      where (ar.ItemTypeId == (int)Enums.ItemType.Article) && ar.ParentId == feed.FeedId
                                      && ar.DatePublished > datelimit
                                      select new Article
                                      {
                                           Title = ar.Title, 
                                           Description = ar.Blurb
                                      }).ToList();
Run Code Online (Sandbox Code Playgroud)

以下比较的每个人都显示与Ellsberg标题/描述不匹配.ie matches1 to matches6都有Count()==0

(请原谅列举的变量名称 - 它们仅用于测试)

   // comparison methods 
CompareOptions compareOptions = CompareOptions.OrdinalIgnoreCase;
CompareOptions compareOptions2 = CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace;
//1
IEnumerable<Article> matches = thisFeedArticles.Where(b =>
    String.Compare(b.Title.Trim().Normalize(), a.Title.Trim().Normalize(), CultureInfo.InvariantCulture, compareOptions) == 0 &&
    String.Compare(b.Description.Trim().Normalize(), a.Description.Trim().Normalize(), CultureInfo.InvariantCulture, compareOptions) == 0
    );

//2
IEnumerable<Article> matches2 = thisFeedArticles.Where(b =>
    String.Compare(b.Title, a.Title, CultureInfo.CurrentCulture, compareOptions2) == 0 &&
    String.Compare(b.Description, a.Description, CultureInfo.CurrentCulture, compareOptions2) == 0
    );

//3
IEnumerable<Article> matches3 = thisFeedArticles.Where(b =>
    String.Compare(b.Title, a.Title, StringComparison.OrdinalIgnoreCase) == 0 &&
    String.Compare(b.Description, a.Description, StringComparison.OrdinalIgnoreCase) == 0
    );

//4
IEnumerable<Article> matches4 = thisFeedArticles.Where(b =>
    b.Title.Equals(a.Title, StringComparison.OrdinalIgnoreCase) &&
    b.Description.Equals(a.Description, StringComparison.OrdinalIgnoreCase)
    );

//5
IEnumerable<Article> matches5 = thisFeedArticles.Where(b =>
    b.Title.Trim().Equals(a.Title.Trim(), StringComparison.InvariantCultureIgnoreCase) &&
    b.Description.Trim().Equals(a.Description.Trim(), StringComparison.InvariantCultureIgnoreCase)
    );

//6
IEnumerable<Article> matches6 = thisFeedArticles.Where(b =>
    b.Title.Trim().Normalize().Equals(a.Title.Trim().Normalize(), StringComparison.OrdinalIgnoreCase) &&
    b.Description.Trim().Normalize().Equals(a.Description.Trim().Normalize(), StringComparison.OrdinalIgnoreCase)
    );


    if (matches.Count() == 0 && matches2.Count() == 0 && matches3.Count() == 0 && matches4.Count() == 0 && matches5.Count() == 0 && matches6.Count() == 0 && matches7.Count() == 0)
    {
    //insert values
    }

    //this if statement was the first approach
    //if (!thisFeedArticles.Any(b => b.Title == a.Title && b.Description == a.Description)
    // {
    // insert
    // }
Run Code Online (Sandbox Code Playgroud)

显然我一次只使用上述选项之一.

在大多数情况下,上述选项确实有效,并且检测到大多数重复,但仍然有重复的问题 - 我只需要了解"裂缝"是什么,所以任何建议都会受到欢迎.

我甚至尝试将字符串转换为字节数组并进行比较(暂时删除该代码,抱歉).

Article目的是如下:

    public class Article
    {
        public string Title;
        public string Description;
    }
Run Code Online (Sandbox Code Playgroud)

更新:

我已经尝试了规范化字符串以及包括IgnoreSymbolsCompareOption,我仍然得到假阴性(不匹配).我注意到的是,撇号似乎在虚假的不匹配中表现出一致的外观; 所以我认为这可能是撇号与单引号即'vs'(等等)的情况,但IgnoreSymbols肯定应该避免这种情况吗?

我找到了几个类似的SO帖子: C#字符串比较忽略空格,回车或换行 字符串比较:InvariantCultureIgnoreCase vs OrdinalIgnoreCase? 下一步:根据以下答案尝试使用正则表达式去除空白区域:https://stackoverflow.com/a/4719009/2261245

更新2 在6比较之后STILL没有返回任何匹配,我意识到必须有另一个因素扭曲结果,所以我尝试了以下

//7
IEnumerable<Article> matches7 = thisFeedArticles.Where(b =>
    Regex.Replace(b.Title, "[^0-9a-zA-Z]+", "").Equals(Regex.Replace(a.Title, "[^0-9a-zA-Z]+", ""), StringComparison.InvariantCultureIgnoreCase) &&
    Regex.Replace(b.Description, "[^0-9a-zA-Z]+", "").Equals(Regex.Replace(a.Description, "[^0-9a-zA-Z]+", ""), StringComparison.InvariantCultureIgnoreCase)
    );
Run Code Online (Sandbox Code Playgroud)

这可以找到其他人错过的比赛!

下面的字符串经过了所有6次比较,但不是第7次:

a.Title.Trim().Normalize()并且a.Title.Trim()都返回:

"更正:鉴定小胶质细胞中独特的TGF-β依赖性分子和功能特征"

DB中的值是:

"更正:鉴定小胶质细胞中独特的TGF-β依赖性分子和功能特征"

更仔细的检查表明德国人的'eszett'特征在DB中与饲料中的特征不同:βvsß

我原本预计至少会有一个比较1-6来挑选它......

有趣的是,经过一些性能比较后,Regex选项绝不是七个中最慢的选项.Normalize似乎比正则表达更加密集!以下是对象包含12077项 Stopwatch时所有七个的持续时间thisFeedArticles

已用时间:00:00:00.0000662
已过时:00:00:00.0000009已用
时间:00:00:00.0000009已用
时间:00:00:00.0000009已用
时间:00:00:00.0000009已用
时间:00:00:00.0000009
时间已过:00:00:00.0000016

Kri*_*ten 5

Unicode 字符串可以是“二进制”不同的,即使它们“语义”相同。

尝试标准化你的字符串。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/System.String.Normalize.aspx