我有一个我想忽略的单词列表,如下所示:
public List<String> ignoreList = new List<String>()
{
"North",
"South",
"East",
"West"
};
对于给定的字符串,请说"14th Avenue North"
我希望能够删除“North”部分,所以基本上是一个在调用时返回"14th Avenue "
的函数。
我觉得我应该能够使用LINQ,正则表达式和替换混合使用,但我无法弄明白。
更大的图景是,我正在尝试编写地址匹配算法。在使用Levenshtein算法评估相似度之前,我想过滤掉“Street”,“North”,“Boulevard”等字样。
答案 0 :(得分:12)
这个怎么样:
string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w)));
或.Net 3:
string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w)).ToArray());
请注意,此方法将字符串拆分为单个单词,因此它只删除整个单词。这样,它就可以正常处理Northampton Way #123
string.Replace
无法处理的地址。
答案 1 :(得分:6)
Regex r = new Regex(string.Join("|", ignoreList.Select(s => Regex.Escape(s)).ToArray()));
string s = "14th Avenue North";
s = r.Replace(s, string.Empty);
答案 2 :(得分:2)
这样的事情应该有效:
string FilterAllValuesFromIgnoreList(string someStringToFilter)
{
return ignoreList.Aggregate(someStringToFilter, (str, filter)=>str.Replace(filter, ""));
}
答案 3 :(得分:2)
简单的for循环有什么问题?
string street = "14th Avenue North";
foreach (string word in ignoreList)
{
street = street.Replace(word, string.Empty);
}
答案 4 :(得分:2)
如果你知道单词列表只包含不需要在正则表达式中转义的字符,那么你可以这样做:
string s = "14th Avenue North";
Regex regex = new Regex(string.Format(@"\b({0})\b",
string.Join("|", ignoreList.ToArray())));
s = regex.Replace(s, "");
结果:
14th Avenue
如果有特殊字符,您需要修复两件事:
\b
与后跟符号的空格不匹配,反之亦然。您可能需要使用外观断言来检查空格(或其他分隔字符,如标点符号)。以下是解决这两个问题的方法:
Regex regex = new Regex(string.Format(@"(?<= |^)({0})(?= |$)",
string.Join("|", ignoreList.Select(x => Regex.Escape(x)).ToArray())));
答案 5 :(得分:1)
如果它是一个短字符串,就像你的例子一样,你可以循环遍历字符串并一次替换一个字符串。如果你想获得幻想,你可以使用LINQ Aggregate方法来实现它:
address = ignoreList.Aggregate(address, (a, s) => a.Replace(s, String.Empty));
如果它是一个大字符串,那将会很慢。相反,您可以通过字符串替换单个运行中的所有字符串,这要快得多。我在this answer中为此做了一个方法。
答案 6 :(得分:1)
LINQ使这简单易读。这需要标准化数据,特别是它区分大小写。
List<string> ignoreList = new List<string>()
{
"North",
"South",
"East",
"West"
};
string s = "123 West 5th St"
.Split(' ') // Separate the words to an array
.ToList() // Convert array to TList<>
.Except(ignoreList) // Remove ignored keywords
.Aggregate((s1, s2) => s1 + " " + s2); // Reconstruct the string
答案 7 :(得分:0)
public static string Trim(string text)
{
var rv = text;
foreach (var ignore in ignoreList)
rv = rv.Replace(ignore, "");
return rv;
}
为Gabe更新
public static string Trim(string text)
{
var rv = "";
var words = text.Split(" ");
foreach (var word in words)
{
var present = false;
foreach (var ignore in ignoreList)
if (word == ignore)
present = true;
if (!present)
rv += word;
}
return rv;
}
答案 8 :(得分:0)
如果你有一个清单,我想你将不得不触摸所有物品。您可以使用所有忽略关键字创建一个大规模的RegEx,并替换为String.Empty
。
这是一个开始:
(^|\s+)(North|South|East|West){1,2}(ern)?(\s+|$)
如果您有一个单一的RegEx用于忽略单词,则可以为要传递给算法的每个短语执行单个替换。
答案 9 :(得分:0)
为什么不保持简单?
public static string Trim(string text)
{
var rv = text.trim();
foreach (var ignore in ignoreList) {
if(tv.EndsWith(ignore) {
rv = rv.Replace(ignore, string.Empty);
}
}
return rv;
}
答案 10 :(得分:0)
如果您愿意,可以使用和表达式来执行此操作,但是使用聚合比使用聚合更容易。我会做这样的事情:
string s = "14th Avenue North"
ignoreList.ForEach(i => s = s.Replace(i, ""));
//result is "14th Avenue "