Удаление символов из строки С#

Вопрос:Как я могу удалить символы из строки? Например: "My name @is ,Wan.;'; Wan". Я хотел бы удалить символы '@', ',', '.', ';', ''' из этой строки, чтобы она стала "My name is Wan Wan" Ответ №1var str = "My name @is ,Wan.;'; Wan"; var charsToRemove = new string[] { "@", ",", ".", ";", "'" };

Вопрос:

Как я могу удалить символы из строки? Например: «My name @is ,Wan.;’; Wan».

Я хотел бы удалить символы ‘@’, ‘,’, ‘.’, ‘;’, »’ из этой строки, чтобы она стала «My name is Wan Wan»

Ответ №1var str = «My name @is ,Wan.;’; Wan»; var charsToRemove = new string[] { «@», «,», «.», «;», «‘» }; foreach (var c in charsToRemove) { str = str.Replace(c, string.Empty); }

Но я могу предложить другой подход, если вы хотите удалить все символы без буквы

var str = «My name @is ,Wan.;’; Wan»; str = new string((from c in str where char.IsWhiteSpace(c) || char.IsLetterOrDigit(c) select c ).ToArray()); Ответ №2

Простой:

String.Join(«», «My name @is ,Wan.;’; Wan».Split(‘@’, ‘,’ ,’.’ ,’;’, »’)); Ответ №3

Звучит как идеальное приложение для RegEx – движок, предназначенный для быстрой обработки текста. В этом случае:

Regex.Replace(«He»ll,o Wo’r.ld», «[@,\.»;’\\]», string.Empty) Ответ №4

Менее специфичный для вашего вопроса, можно удалить ВСЕ пунктуацию из строки (кроме пробела) белым списком допустимых символов в регулярном выражении:

string dirty = «My name @is ,Wan.;’; Wan»; // only space, capital A-Z, lowercase a-z, and digits 0-9 are allowed in the string string clean = Regex.Replace(dirty, «[^A-Za-z0-9 ]», «»);

Обратите внимание, что после этого есть пробел, чтобы не удалять пробелы из вашего предложения. Третий аргумент – это пустая строка, которая заменяет любую подстроку, не принадлежащую регулярному выражению.

Ответ №5 string x = «My name @is ,Wan.;’; Wan»; string modifiedString = x.Replace(«@», «»).Replace(«,», «»).Replace(«.», «»).Replace(«;», «»).Replace(«‘», «»); Ответ №6

Сравнение различных предложений (а также сравнение в контексте односимвольных замен с различными размерами и позициями цели).

В этом конкретном случае разбиение по целям и объединение замен (в данном случае пустая строка) является самым быстрым, по крайней мере, в 3 раза. В конечном счете, производительность различается в зависимости от количества замен, где замены находятся в источник и размер источника. #ymmv

Результаты

(полные результаты здесь)

| Test | Compare | Elapsed | |—————————|———|———————————————————————| | SplitJoin | 1.00x | 29023 ticks elapsed (2.9023 ms) [in 10K reps, 0.00029023 ms per] | | Replace | 2.77x | 80295 ticks elapsed (8.0295 ms) [in 10K reps, 0.00080295 ms per] | | RegexCompiled | 5.27x | 152869 ticks elapsed (15.2869 ms) [in 10K reps, 0.00152869 ms per] | | LinqSplit | 5.43x | 157580 ticks elapsed (15.758 ms) [in 10K reps, 0.0015758 ms per] | | Regex, Uncompiled | 5.85x | 169667 ticks elapsed (16.9667 ms) [in 10K reps, 0.00169667 ms per] | | Regex | 6.81x | 197551 ticks elapsed (19.7551 ms) [in 10K reps, 0.00197551 ms per] | | RegexCompiled Insensitive | 7.33x | 212789 ticks elapsed (21.2789 ms) [in 10K reps, 0.00212789 ms per] | | Regex Insentive | 7.52x | 218164 ticks elapsed (21.8164 ms) [in 10K reps, 0.00218164 ms per] |

Test Harness (LinqPad)

(примечание: Perf и Vs – это временные расширения, которые я написал)

void test(string title, string sample, string target, string replacement) { var targets = target.ToCharArray(); var tox = «[» + target + «]»; var x = new Regex(tox); var xc = new Regex(tox, RegexOptions.Compiled); var xci = new Regex(tox, RegexOptions.Compiled | RegexOptions.IgnoreCase); // no, don’t dump the results var p = new Perf/*<string>*/(); p.Add(string.Join(» «, title, «Replace»), n => targets.Aggregate(sample, (res, curr) => res.Replace(new string(curr, 1), replacement))); p.Add(string.Join(» «, title, «SplitJoin»), n => String.Join(replacement, sample.Split(targets))); p.Add(string.Join(» «, title, «LinqSplit»), n => String.Concat(sample.Select(c => targets.Contains(c) ? replacement : new string(c, 1)))); p.Add(string.Join(» «, title, «Regex»), n => Regex.Replace(sample, tox, replacement)); p.Add(string.Join(» «, title, «Regex Insentive»), n => Regex.Replace(sample, tox, replacement, RegexOptions.IgnoreCase)); p.Add(string.Join(» «, title, «Regex, Uncompiled»), n => x.Replace(sample, replacement)); p.Add(string.Join(» «, title, «RegexCompiled»), n => xc.Replace(sample, replacement)); p.Add(string.Join(» «, title, «RegexCompiled Insensitive»), n => xci.Replace(sample, replacement)); var trunc = 40; var header = sample.Length > trunc ? sample.Substring(0, trunc) + «…» : sample; p.Vs(header); } void Main() { // also see https://stackoverflow.com/questions/7411438/remove-characters-from-c-sharp-string «Control».Perf(n => { var s = «*»; }); var text = «My name @is ,Wan.;’; Wan»; var clean = new[] { ‘@’, ‘,’, ‘.’, ‘;’, »’ }; test(«stackoverflow», text, string.Concat(clean), string.Empty); var target = «o»; var f = «x»; var replacement = «1»; var fillers = new Dictionary<string, string> { { «short», new String(f[0], 10) }, { «med», new String(f[0], 300) }, { «long», new String(f[0], 1000) }, { «huge», new String(f[0], 10000) } }; var formats = new Dictionary<string, string> { { «start», «{0}{1}{1}» }, { «middle», «{1}{0}{1}» }, { «end», «{1}{1}{0}» } }; foreach(var filler in fillers) foreach(var format in formats) { var title = string.Join(«-«, filler.Key, format.Key); var sample = string.Format(format.Value, target, filler.Value); test(title, sample, target, replacement); } } Ответ №7

Самый простой способ – использовать String.Replace:

String s = string.Replace(«StringToReplace», «NewString»); Ответ №8

Еще одно простое решение:

var forbiddenChars = @»@,.;'».ToCharArray(); var dirty = «My name @is ,Wan.;’; Wan»; var clean = new string(dirty.Where(c => !forbiddenChars.Contains(c)).ToArray()); Ответ №9new List<string> { «@», «,», «.», «;», «‘» }.ForEach(m => str = str.Replace(m, «»)); Ответ №10

Строка – это только массив символов, поэтому используйте Linq для замены (аналогично вышеописанному Албину, кроме использования linq содержит инструкцию для замены):

var resultString = new string( (from ch in «My name @is ,Wan.;’; Wan» where ! @»@,.;'».Contains(ch) select ch).ToArray());

Первая строка – это строка для замены символов и
вторая – простая строка, содержащая символы

Ответ №11

Я мог бы также выбросить это здесь.

Сделайте расширение для удаления символов из строки:

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(‘@’, ‘,’, ‘.’, ‘;’, »’); Ответ №12

Много хороших ответов здесь, здесь мое дополнение вместе с несколькими модульными тестами, которые можно использовать для проверки правильности, мое решение похоже на @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]); } } Ответ №13

Кажется, что самый короткий путь – объединить 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»

Смотрите демонстрацию С#. Обратите внимание, что string.Concat является ярлыком для string.Join(«», …).

Обратите внимание, что использование регулярного выражения для удаления отдельных известных символов по-прежнему возможно для динамического создания, хотя считается, что регулярное выражение работает медленнее. Тем не менее, вот способ создания такого динамического регулярного выражения (где вам нужен только класс символов):

var pattern = $»[{Regex.Escape(new string(chrs))}]+»; var result = Regex.Replace(input, pattern, string.Empty);

Смотрите еще одну демонстрацию С#. Регулярное выражение будет выглядеть как [@,.;’]+ (сопоставление одного или нескольких (+) последовательных вхождений @, ,, ., ; или ‘), где точка не должна быть экранирована, но Regex.Escape будет необходимо, чтобы избежать других символов, которые должны быть экранированы, например , ^, ] или -, чья позиция внутри класса символов вы не можете предсказать.

Ответ №14

Старая школа на месте copy/stomp:

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

Не уверен в эффективности w.r.t. другие методы (т.е. накладные расходы на все вызовы функций и экземпляры, которые возникают как побочный эффект при выполнении С#).

Ответ №15

Я делаю его методом расширения и с строковым массивом, я думаю, что string[] более полезен, чем char[], потому что 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[]{ «@», «,», «.», «;», «\»}); Ответ №16

Мне нужно было удалить специальные символы из файла XML. Вот как я это сделал. char.ToString() является героем в этом коде.

string item = «<item type=»line» />» char DC4 = (char)0x14; string fixed = item.Replace(DC4.ToString(), string.Empty); Ответ №17new[] { ‘,’, ‘.’, ‘;’, »’, ‘@’ } .Aggregate(«My name @is ,Wan.;’; Wan», (s, c) => s.Replace(c.ToString(), string.Empty)); Ответ №18

Вот метод, который я написал, который использует немного другой подход. Вместо указания символов для удаления я сообщаю своему методу, какие символы я хочу сохранить – он удалит все остальные символы.

В примере с OP он хочет сохранить только алфавитные символы и пробелы. Вот как будет выглядеть вызов моего метода (С# demo):

var str = «My name @is ,Wan.;’; Wan»; // «My name is Wan Wan» var result = RemoveExcept(str, alphas: true, spaces: true);

Вот мой метод:

/// <summary> /// Returns a copy of the original string containing only the set of whitelisted characters. /// </summary> /// <param name=»value»>The string that will be copied and scrubbed.</param> /// <param name=»alphas»>If true, all alphabetical characters (a-zA-Z) will be preserved; otherwise, they will be removed.</param> /// <param name=»numerics»>If true, all alphabetical characters (a-zA-Z) will be preserved; otherwise, they will be removed.</param> /// <param name=»dashes»>If true, all alphabetical characters (a-zA-Z) will be preserved; otherwise, they will be removed.</param> /// <param name=»underlines»>If true, all alphabetical characters (a-zA-Z) will be preserved; otherwise, they will be removed.</param> /// <param name=»spaces»>If true, all alphabetical characters (a-zA-Z) will be preserved; otherwise, they will be removed.</param> /// <param name=»periods»>If true, all decimal characters («.») will be preserved; otherwise, they will be removed.</param> public static string RemoveExcept(string value, bool alphas = false, bool numerics = false, bool dashes = false, bool underlines = false, bool spaces = false, bool periods = false) { if (string.IsNullOrWhiteSpace(value)) return value; if (new[] { alphas, numerics, dashes, underlines, spaces, periods }.All(x => x == false)) return value; var whitelistChars = new HashSet<char>(string.Concat( alphas ? «abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ» : «», numerics ? «01234567890» : «», dashes ? «-» : «», underlines ? «_» : «», periods ? «.» : «», spaces ? » » : «» ).ToCharArray()); var scrubbedValue = value.Aggregate(new StringBuilder(), (sb, @char) => { if (whitelistChars.Contains(@char)) sb.Append(@char); return sb; }).ToString(); return scrubbedValue; } Ответ №19

Если вы хотите заменить ‘[‘ ‘]’, вы можете попробовать это:

foreach(var c in «[ «]») { string s = c + «»; inputText = inputText.Replace(s, «»); } Ответ №20

Это мощный метод, который я обычно использую в том же случае:

private string Normalize(string text) { return string.Join(«», from ch in text where char.IsLetterOrDigit(ch) || char.IsWhiteSpace(ch) select ch); }

Наслаждайтесь…

Оцените статью
Добавить комментарий