LINQ lambda表达式替换字符串中的多个字符?

是否有可能编写一个lambda表达式,它将迭代对象数组并替换其中一个属性中的’X’,’Y’,”和’Z’的所有出现?

例如

return query.Select(x => { x.SomePropertyName= x.SomePropertyName.Trim().Replace(' ', "_"); return x; }).ToList(); 

出于某种原因,当我需要替换多个字符时,上面的查询不会替换单个字符。

谢谢

当我想用一个单独的其他字符替换多个字符中的一个时,我经常使用string.Split和string.Join的组合:

 char[] unwanted = new[] {'X', 'Y', 'Z'}; query = query.Select(x => { x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)); return x; }); 

这将用'_'替换任何'X''Y''Z' '_' 。 您可以将其与您选择的循环结构相结合。

正如评论中所讨论的,在这种情况下,使用Select并不会真正添加任何值。 一个普通的foreach循环可以完成这项工作,甚至可以生成更紧凑的代码:

 char[] unwanted = new[] {'X', 'Y', 'Z'}; foreach(var x in query) { x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)); }; 

如果要使用LINQ,可以使用Select,ToArray和String(char [])构造函数,如下所示:

 var result = query.ToList(); foreach (var x in result) { x.SomeProperty = new string(x.SomeProperty .Select(c => (c == 'X' || ... || c == ' ') ? '_' : c) .ToArray()); } 

请注意,LINQ不是用于引起副作用,而是用于从现有的枚举中创建新的枚举。 所以foreach循环在这里更好。


但为什么不是简单的一系列替换呼叫呢?

 var result = query.ToList(); foreach (var x in result) { x.SomeProperty = x.SomeProperty .Replace('X', '_') .Replace('Y', '_') .Replace('Z', '_') .Replace(' ', '_'); } 

或者您是否尝试用一系列字符替换单个字符? 然后使用带有两个字符串的String.Replace重载:

 var result = query.ToList(); foreach (var x in result) { x.SomeProperty = x.SomeProperty.Replace(" ", "ABC"); } 

如果您想使用正则表达式,可以执行以下操作:

 query.Select( x => { x.SomePropertyName = Regex.Replace(x.SomePropertyName, @"[XYZ\s]", "_"); return x; }) 

虽然您请求了LINQ,但LINQ的这种(ab)使用依赖于副作用并使代码混乱。 使用对象数组的替代方法(在您的问题中就是这种情况)是使用Array.ForEach方法 :

 // using Fredrik Mörk's approach Array.ForEach(query, x => x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted))); // using Regex Array.ForEach(query, x => x.SomePropertyName = Regex.Replace(x.SomePropertyName, "[XYZ]", "_", RegexOptions.IgnoreCase)); 

当然使用正则表达式需要一些知识。 请注意使用在正则表达式中具有特殊含义的元字符。 您可以使用Regex.Escape方法清理角色。

循环遍历字符串中的每个字符,并在必要时替换它。

  var xyz = new HashSet(new[] { 'X', 'Y', 'Z' }); char replacement = '_'; var results = query .Select(x => { var value = x.SomePropertyName .Trim() .Select(y => xyz.Contains(y) ? replacement : y) .ToArray(); x.SomePropertyName = new string(value); return x; }) .ToList();