문자열에서 마지막 단어 바꾸기-C #


82

문자열에서 단어의 마지막 항목을 바꿔야하는 문제가 있습니다.

상황 : 다음 형식의 문자열이 제공됩니다.

string filePath ="F:/jan11/MFrame/Templates/feb11";

그런 다음 다음 TnaName과 같이 바꿉니다.

filePath = filePath.Replace(TnaName, ""); // feb11 is TnaName

이것은 작동하지만 때 나는 문제가 TnaName내와 동일합니다 folder name. 이런 일이 발생하면 다음과 같은 문자열을 얻게됩니다.

F:/feb11/MFrame/Templates/feb11

지금은 모두 발생 대체하고 TnaName과를 feb11. 내 문자열에서 마지막 단어 만 바꿀 수있는 방법이 있습니까?

참고 : feb11TnaName- 문제가되지 않습니다 다른 프로세스에서 유래한다.


경로의 마지막 부분을 교체하는 것이 유일한 목표입니까? (즉부터이며, /이후?)
사이먼 화이트 헤드

마지막 부분 repalce가 아니라 마지막 TnaName경로에 더 많은 것이 있지만 질문에 대한 샘플 만 생성합니다. 감사합니다 .
Shree

1
이 문자열은 항상 무언가에 대한 경로입니까? System.IO.Path 클래스를 사용하는 것이 좋습니다.
Yuriy Rozhovetskiy 2013

예 문자열은 항상 무언가에 대한 경로입니다.
Shree

답변:


176

다음은 문자열의 마지막 발생을 대체하는 함수입니다.

public static string ReplaceLastOccurrence(string Source, string Find, string Replace)
{
        int place = Source.LastIndexOf(Find);

        if(place == -1)
           return Source;

        string result = Source.Remove(place, Find.Length).Insert(place, Replace);
        return result;
}
  • Source 작업을 수행 할 문자열입니다.
  • Find 바꿀 문자열입니다.
  • Replace 바꿀 문자열입니다.

일반적인 기능에 감사드립니다. 작동하며 @Simon에도 동의합니다.
Shree

6
어쩌면 일치가 없다, 조심 (예 Place == -1)
알리레자 누리

7
일치하지 않는 경우 빈 문자열보다 소스를 반환하는 것이 더 논리적 일 수 있습니다.
Sasha

2
"return Source;"를 반환해야합니다. "return sting.Empty;"대신 찾기 문자열이 발견되지 않으면 논리가 실패했기 때문입니다.
Jignesh Variya

1
(와 string Source as in : 사이에 추가 하면 문자열 public static string ReplaceLastOccurance(this string Source...의 마지막 항목을 대체하는 데 사용할 수있는 멋진 확장 방법이 있습니다.
beaudetious

12

을 사용 string.LastIndexOf()하여 문자열의 마지막 발생 인덱스를 찾은 다음 하위 문자열을 사용하여 솔루션을 찾습니다.


7

수동으로 교체해야합니다.

int i = filePath.LastIndexOf(TnaName);
if (i >= 0)
    filePath = filePath.Substring(0, i) + filePath.Substring(i + TnaName.Length);

3

Regex를 사용할 수없는 이유를 모르겠습니다.

public static string RegexReplace(this string source, string pattern, string replacement)
{
  return Regex.Replace(source,pattern, replacement);
}

public static string ReplaceEnd(this string source, string value, string replacement)
{
  return RegexReplace(source, $"{value}$", replacement);
}

public static string RemoveEnd(this string source, string value)
{
  return ReplaceEnd(source, value, string.Empty);
}

용법:

string filePath ="F:/feb11/MFrame/Templates/feb11";
filePath = filePath.RemoveEnd("feb11"); // F:/feb11/MFrame/Templates/
filePath = filePath.ReplaceEnd("feb11","jan11"); // F:/feb11/MFrame/Templates/jan11

1
Regex.Escape () 값이 있어야합니다.
jcox

그러니까 return Regex.Replace(Regex.Replace(source),pattern, replacement);?
toddmo

누군가 ReplaceEnd ( "(foobar)", ")", "thenewend")를 호출한다고 가정합니다. ") $"는 잘못된 정규식이므로 함수가 발생합니다. 이것은 작동합니다 : return RegexReplace (source, Regex.Escape (value) + "$", replacement); RemoveEnd에 대해서도 마찬가지입니다.
jcox

@jcox, 이중 이스케이프를 피하는 방법을 알아낼 수 없었습니다. b / c 각 함수는 공용이므로 여러 잠재적 호출 경로가 있습니다. 제 경우에는 특수 문자에 사용하지 않았지만 요점을 알았습니다.
toddmo

@toddmo ReplaceEnd 및 RemoveEnd가 Regex.Replace를 직접 호출하도록했습니다. 그래도 주제에서 벗어난 것 같습니다. 사용자 입력을 정규식 패턴에 삽입하는 것이 까다로울 수 있다는 것을 사람들이 알고 있기를 바랍니다. XML 또는 SQL에 입력을 삽입하는 것과 유사합니다. 이스케이프 메커니즘이 필요합니다.
jcox

1

네임 스페이스 의 Path클래스를 사용할 수 있습니다 System.IO.

string filePath = "F:/jan11/MFrame/Templates/feb11";

Console.WriteLine(System.IO.Path.GetDirectoryName(filePath));

0

솔루션은 한 줄로 훨씬 더 간단하게 구현할 수 있습니다.

 static string ReplaceLastOccurrence(string str, string toReplace, string replacement)
    {
        return Regex.Replace(str, $@"^(.*){toReplace}(.*?)$", $"$1{replacement}$2");
    }

이로써 우리는 정규식 별표 연산자의 탐욕을 이용합니다. 이 함수는 다음과 같이 사용됩니다.

var s = "F:/feb11/MFrame/Templates/feb11";
var tnaName = "feb11";
var r = ReplaceLastOccurrence(s,tnaName, string.Empty);

0
var lastIndex = filePath.LastIndexOf(TnaName);

filePath = filePath.Substring(0, lastIndex);

2
코드 전용 답변이 질문에 답할 수 있지만 코드에 대한 컨텍스트,이 코드가 작동하는 이유 및 추가 읽을 문서에 대한 일부 참조를 제공하여 답변의 품질을 크게 향상시킬 수 있습니다. 에서 답변하는 방법 : "간결은 허용되지만 풀러 설명이 더 낫다."
Pranav Hosangadi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.