我该如何从字符串中删除字符?比如:"My name @is ,Wan.;'; Wan"
。
我想要从该字符串中删除字符'@',',','.',';','\''
,使其变为"My name is Wan Wan"
new List<string> { "@", ",", ".", ";", "'" }.ForEach(m => str = str.Replace(m, ""));
我来翻译一下。
制作一个扩展程序,用于从字符串中删除字符:
public static string RemoveChars(this string input, params char[] chars)
{
var sb = new StringBuilder();
for (int i = 0; i < input.Length; i++)
{
if (!chars.Contains(input[i]))
sb.Append(input[i]);
}
return sb.ToString();
}
它可以这样使用:
string str = "My name @is ,Wan.;'; Wan";
string cleanedUpString = str.RemoveChars('@', ',', '.', ';', '\'');
string str = "My name @is ,Wan.;'; Wan".RemoveChars('@', ',', '.', ';', '\'');
似乎最简单的方法是将LINQ和string.Concat
组合使用:
var input = @"My name @is ,Wan.;'; Wan";
var chrs = new[] {'@', ',', '.', ';', '\''};
var result = string.Concat(input.Where(c => !chrs.Contains(c)));
// => result = "My name is Wan Wan"
请查看C#演示。请注意,string.Concat
是string.Join(“”,...)
的快捷方式。
请注意,使用正则表达式删除单个已知字符仍然可以动态构建,尽管认为正则表达式速度较慢。 但是,这里有一种构建此类动态正则表达式的方法(其中您只需要一个字符类):
var pattern = $"[{Regex.Escape(new string(chrs))}]+";
var result = Regex.Replace(input, pattern, string.Empty);
[@,\.;']+
(匹配一个或多个连续出现的 @
、,
、.
、;
或 '
字符),其中点号不必转义,但是 Regex.Escape
将需要用于转义其他必须转义的字符,例如 \ ,^
,]
或 -
,其在字符类内的位置无法预测。
字符串只是一个字符数组,因此可以使用Linq进行替换(与上面的Albin类似,但使用Linq包含语句进行替换):
var resultString = new string(
(from ch in "My name @is ,Wan.;'; Wan"
where ! @"@,.;\'".Contains(ch)
select ch).ToArray());
这里有一种很好的方法可以从文件名中删除无效字符:
string.Join(string.Empty, filename.Split(System.IO.Path.GetInvalidFileNameChars()));
这里有很多好的答案,我来补充一下,还提供了几个单元测试以帮助测试正确性。我的解决方案与@Rianne的相似,但使用ISet提供替换字符的O(1)查找时间(也类似于@Albin Sunnanbo的Linq解决方案)。
using System;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// Returns a string with the specified characters removed.
/// </summary>
/// <param name="source">The string to filter.</param>
/// <param name="removeCharacters">The characters to remove.</param>
/// <returns>A new <see cref="System.String"/> with the specified characters removed.</returns>
public static string Remove(this string source, IEnumerable<char> removeCharacters)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (removeCharacters == null)
{
throw new ArgumentNullException("removeCharacters");
}
// First see if we were given a collection that supports ISet
ISet<char> replaceChars = removeCharacters as ISet<char>;
if (replaceChars == null)
{
replaceChars = new HashSet<char>(removeCharacters);
}
IEnumerable<char> filtered = source.Where(currentChar => !replaceChars.Contains(currentChar));
return new string(filtered.ToArray());
}
NUnit(2.6+)的测试在这里
using System;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
[TestFixture]
public class StringExtensionMethodsTests
{
[TestCaseSource(typeof(StringExtensionMethodsTests_Remove_Tests))]
public void Remove(string targetString, IEnumerable<char> removeCharacters, string expected)
{
string actual = StringExtensionMethods.Remove(targetString, removeCharacters);
Assert.That(actual, Is.EqualTo(expected));
}
[TestCaseSource(typeof(StringExtensionMethodsTests_Remove_ParameterValidation_Tests))]
public void Remove_ParameterValidation(string targetString, IEnumerable<char> removeCharacters)
{
Assert.Throws<ArgumentNullException>(() => StringExtensionMethods.Remove(targetString, removeCharacters));
}
}
internal class StringExtensionMethodsTests_Remove_Tests : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new TestCaseData("My name @is ,Wan.;'; Wan", new char[] { '@', ',', '.', ';', '\'' }, "My name is Wan Wan").SetName("StringUsingCharArray");
yield return new TestCaseData("My name @is ,Wan.;'; Wan", new HashSet<char> { '@', ',', '.', ';', '\'' }, "My name is Wan Wan").SetName("StringUsingISetCollection");
yield return new TestCaseData(string.Empty, new char[1], string.Empty).SetName("EmptyStringNoReplacementCharactersYieldsEmptyString");
yield return new TestCaseData(string.Empty, new char[] { 'A', 'B', 'C' }, string.Empty).SetName("EmptyStringReplacementCharsYieldsEmptyString");
yield return new TestCaseData("No replacement characters", new char[1], "No replacement characters").SetName("StringNoReplacementCharactersYieldsString");
yield return new TestCaseData("No characters will be replaced", new char[] { 'Z' }, "No characters will be replaced").SetName("StringNonExistantReplacementCharactersYieldsString");
yield return new TestCaseData("AaBbCc", new char[] { 'a', 'C' }, "ABbc").SetName("CaseSensitivityReplacements");
yield return new TestCaseData("ABC", new char[] { 'A', 'B', 'C' }, string.Empty).SetName("AllCharactersRemoved");
yield return new TestCaseData("AABBBBBBCC", new char[] { 'A', 'B', 'C' }, string.Empty).SetName("AllCharactersRemovedMultiple");
yield return new TestCaseData("Test That They Didn't Attempt To Use .Except() which returns distinct characters", new char[] { '(', ')' }, "Test That They Didn't Attempt To Use .Except which returns distinct characters").SetName("ValidateTheStringIsNotJustDistinctCharacters");
}
}
internal class StringExtensionMethodsTests_Remove_ParameterValidation_Tests : IEnumerable
{
public IEnumerator GetEnumerator()
{
yield return new TestCaseData(null, null);
yield return new TestCaseData("valid string", null);
yield return new TestCaseData(null, new char[1]);
}
}
这是我通常在相同情况下使用的一种强大的方法:
private string Normalize(string text)
{
return string.Join("",
from ch in text
where char.IsLetterOrDigit(ch) || char.IsWhiteSpace(ch)
select ch);
}
Enjoy...
我将其制作为扩展方法,并使用字符串数组,我认为string[]
比char[]
更有用,因为字符也可以是字符串:
public static class Helper
{
public static string RemoverStrs(this string str, string[] removeStrs)
{
foreach (var removeStr in removeStrs)
str = str.Replace(removeStr, "");
return str;
}
}
string myname = "My name @is ,Wan.;'; Wan";
string result = myname.RemoveStrs(new[]{ "@", ",", ".", ";", "\\"});
new[] { ',', '.', ';', '\'', '@' }
.Aggregate("My name @is ,Wan.;'; Wan", (s, c) => s.Replace(c.ToString(), string.Empty));
老派的就地复制/覆盖:
private static string RemoveDirtyCharsFromString(string in_string)
{
int index = 0;
int removed = 0;
byte[] in_array = Encoding.UTF8.GetBytes(in_string);
foreach (byte element in in_array)
{
if ((element == ' ') ||
(element == '-') ||
(element == ':'))
{
removed++;
}
else
{
in_array[index] = element;
index++;
}
}
Array.Resize<byte>(ref in_array, (in_array.Length - removed));
return(System.Text.Encoding.UTF8.GetString(in_array, 0, in_array.Length));
}
对于其他方法的效率(即在C#执行期间发生的所有函数调用和实例化的开销),我不确定。