gpt4 book ai didi

C# 字符串比较等于 false

转载 作者:太空狗 更新时间:2023-10-29 20:30:33 25 4
gpt4 key购买 nike

我有一个字符串比较问题,在大多数情况下,它的行为符合预期,但给我留下了大量重复的数据库插入,因为我的代码没有将字符串对检测为重复。

我以为我已经将它缩小到一个文化问题(西里尔字符),我解决了这个问题,但我现在得到了“漏报”(两个明显相等的字符串显示为不相等)。

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

我检查过的类似 SO 问题:

下面是一个正在比较的字符串的例子:(标题和描述)

feed title: Ellsberg: He's a hero

feed desc: Daniel Ellsberg tells CNN's Don Lemon that NSA leaker Edward Snowden showed courage, has done an enormous service.

db title: Ellsberg: He's a hero

db desc: Daniel Ellsberg tells CNN's Don Lemon that NSA leaker Edward Snowden showed courage, has done an enormous service.

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

//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();

以下比较中的每个人都与 Ellsberg 标题/描述不匹配。即 matches1 到 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
// }

显然,我一次只使用了上述选项之一。

在大多数情况下,上述选项确实有效并且检测到大多数重复项,但仍有重复项从裂缝中溜走 - 我只需要了解“裂缝”是什么,所以任何建议都是最受欢迎的。

我什至尝试将字符串转换为字节数组并进行比较(刚才删除了该代码,抱歉)。

Article对象如下:

    public class Article
{
public string Title;
public string Description;
}

更新:

我已经尝试规范化字符串以及包括 IgnoreSymbols CompareOption,但我仍然得到假阴性(不匹配)。不过,我注意到的是,撇号似乎在错误的不匹配中始终如一地出现;所以我认为这可能是撇号与单引号的情况,即 ' 与 '(等等),但 IgnoreSymbols 肯定应该避免这种情况吗?

我发现了几个类似的 SO 帖子: C# string comparison ignoring spaces, carriage return or line breaks String comparison: InvariantCultureIgnoreCase vs OrdinalIgnoreCase?下一步:按照这个答案尝试使用正则表达式去除空格:https://stackoverflow.com/a/4719009/2261245

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

//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)
);

这确实能找到其他人遗漏的匹配项!

下面的字符串通过了所有 6 次比较,但没有通过第 7 次比较:

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

"Corrigendum: Identification of a unique TGF-β–dependent molecular and functional signature in microglia"

数据库中的值是:

"Corrigendum: Identification of a unique TGF-ß–dependent molecular and functional signature in microglia"

仔细检查表明,与来自提要的内容相比,数据库中的德语“eszett”字符不同:β 与 ß

我希望比较 1-6 中至少有一个能够接受这一点......

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

Time elapsed: 00:00:00.0000662
Time elapsed: 00:00:00.0000009
Time elapsed: 00:00:00.0000009
Time elapsed: 00:00:00.0000009
Time elapsed: 00:00:00.0000009
Time elapsed: 00:00:00.0000009
Time elapsed: 00:00:00.0000016

最佳答案

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

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

关于C# 字符串比较等于 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25809230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com