Мне нужно удалить первое (и ТОЛЬКО первое) вхождение строки из другой строки.
Вот пример замены строки "\\Iteration"
. Этот:
ProjectName \ Iteration \ Release1 \ Iteration1
станет таким:
ProjectName \ Release1 \ Iteration1
Вот код, который делает это:
const string removeString = "\\Iteration";
int index = sourceString.IndexOf(removeString);
int length = removeString.Length;
String startOfString = sourceString.Substring(0, index);
String endOfString = sourceString.Substring(index + length);
String cleanPath = startOfString + endOfString;
Похоже, много кода.
Итак, мой вопрос таков: есть ли более чистый / более читаемый / более сжатый способ сделать это?
æ
иae
считаются равными. Попытка удалитьpaedia
изEncyclopædia
приведет к сбоюArgumentOutOfRangeException
, поскольку вы пытаетесь удалить 6 символов, когда соответствующая подстрока содержит только 5.sourceString.IndexOf(removeString, StringComparison.Ordinal)
чтобы избежать исключения.string myString = sourceString.Remove(sourceString.IndexOf(removeString),removeString.Length);
РЕДАКТИРОВАТЬ: @OregonGhost прав. Я сам разбивал сценарий на условные обозначения, чтобы проверить наличие такого случая, но я работал в предположении, что строки были даны как принадлежащие друг другу по какому-то требованию. Возможно, ожидается, что бизнес-правила обработки исключений уловят эту возможность. Я сам использовал бы пару дополнительных строк для выполнения условных проверок, а также чтобы сделать его более читабельным для младших разработчиков, которым, возможно, не хватает времени, чтобы прочитать его достаточно внимательно.
источник
sourceString.Replace(removeString, "");
источник
Написал для этого быстрый тест TDD
[TestMethod] public void Test() { var input = @"ProjectName\Iteration\Release1\Iteration1"; var pattern = @"\\Iteration"; var rgx = new Regex(pattern); var result = rgx.Replace(input, "", 1); Assert.IsTrue(result.Equals(@"ProjectName\Release1\Iteration1")); }
rgx.Replace (ввод, "", 1); говорит искать во вводе все, что соответствует шаблону, с "", 1 раз.
источник
Вы можете использовать метод расширения для развлечения. Обычно я не рекомендую прикреплять методы расширения к такому классу общего назначения, как строка, но, как я уже сказал, это весело. Я позаимствовал ответ @Luke, так как нет смысла изобретать колесо заново.
[Test] public void Should_remove_first_occurrance_of_string() { var source = "ProjectName\\Iteration\\Release1\\Iteration1"; Assert.That( source.RemoveFirst("\\Iteration"), Is.EqualTo("ProjectName\\Release1\\Iteration1")); } public static class StringExtensions { public static string RemoveFirst(this string source, string remove) { int index = source.IndexOf(remove); return (index < 0) ? source : source.Remove(index, remove.Length); } }
источник
IsValidIBAN(this string input)
было бы слишком конкретно, чтобы иметь его в строке.Если вам нужен простой способ решения этой проблемы. (Может использоваться как расширение)
Увидеть ниже:
public static string RemoveFirstInstanceOfString(this string value, string removeString) { int index = value.IndexOf(removeString, StringComparison.Ordinal); return index < 0 ? value : value.Remove(index, removeString.Length); }
Применение:
string valueWithPipes = "| 1 | 2 | 3"; string valueWithoutFirstpipe = valueWithPipes.RemoveFirstInstanceOfString("|"); //Output, valueWithoutFirstpipe = " 1 | 2 | 3";
Вдохновленный и модифицированный ответами @LukeH и @Mike.
Не забудьте StringComparison.Ordinal, чтобы избежать проблем с настройками культуры. https://www.jetbrains.com/help/resharper/2018.2/StringIndexOfIsCultureSpecific.1.html
источник
Я определенно согласен с тем, что это идеально подходит для метода расширения, но я думаю, что его можно немного улучшить.
public static string Remove(this string source, string remove, int firstN) { if(firstN <= 0 || string.IsNullOrEmpty(source) || string.IsNullOrEmpty(remove)) { return source; } int index = source.IndexOf(remove); return index < 0 ? source : source.Remove(index, remove.Length).Remove(remove, --firstN); }
Это немного рекурсии, что всегда весело.
Вот и простой модульный тест:
[TestMethod()] public void RemoveTwiceTest() { string source = "look up look up look it up"; string remove = "look"; int firstN = 2; string expected = " up up look it up"; string actual; actual = source.Remove(remove, firstN); Assert.AreEqual(expected, actual); }
источник