[c#] 다른 문자열에서 첫 번째 부분 문자열을 제거하는 가장 간단한 방법
다른 문자열에서 문자열의 첫 번째 (그리고 첫 번째 만) 발생을 제거해야합니다.
다음은 문자열을 대체하는 예 "\\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;
그것은 많은 코드처럼 보입니다.
그래서 내 질문은 이것입니다 : 이것을 수행하는 더 깨끗하고 / 더 읽기 쉽고, 더 간결한 방법이 있습니까?
답변
int index = sourceString.IndexOf(removeString);
string cleanPath = (index < 0)
? sourceString
: sourceString.Remove(index, removeString.Length);
답변
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 (input, “”, 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);
}
}
답변
이 문제를 해결하는 간단한 방법을 원할 경우. (확장자로 사용 가능)
아래를 참조하십시오.
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의 답변에서 영감을 얻고 수정했습니다.
Culture 설정 문제를 방지하려면 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);
}