Thay thế lần xuất hiện cuối cùng của một từ trong một chuỗi - C #


82

Tôi gặp sự cố trong đó tôi cần thay thế lần xuất hiện cuối cùng của một từ trong một chuỗi.

Tình huống: Tôi được cung cấp một chuỗi có định dạng sau:

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

Sau đó tôi thay thế TnaNamenhư thế này:

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

Điều này hoạt động, nhưng tôi có một vấn đề khi TnaNamegiống như của tôi folder name. Khi điều này xảy ra, tôi sẽ nhận được một chuỗi như thế này:

F:/feb11/MFrame/Templates/feb11

Bây giờ nó đã thay thế cả hai lần xuất hiện của TnaNamevới feb11. Có cách nào để tôi chỉ có thể thay thế lần xuất hiện cuối cùng của từ trong chuỗi của mình không?

Lưu ý: feb11là TnaNamequy trình đến từ quy trình khác - đó không phải là vấn đề.


Mục tiêu duy nhất của bạn có phải là thay thế phần cuối cùng của con đường không? (nghĩa là, từ /trở đi?)
— Simon Whitehead

Không có phần cuối chỉ repalce cuối cùng TnaNamecó nhiều hơn trong đường dẫn nhưng tôi chỉ tạo mẫu cho câu hỏi. Cảm ơn.
— Shree

1
Chuỗi này luôn luôn là một đường dẫn đến một cái gì đó? Xem xét sử dụng lớp System.IO.Path nếu nó được.
— Yuriy Rozhovetskiy

Có chuỗi luôn luôn là một đường dẫn đến một cái gì đó.
— Shree

Câu trả lời:


176

Đây là hàm để thay thế lần xuất hiện cuối cùng của một chuỗi

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 là chuỗi mà bạn muốn thực hiện thao tác.
  • Find là chuỗi mà bạn muốn thay thế.
  • Replace là chuỗi mà bạn muốn thay thế nó.

Cảm ơn rất nhiều vì chức năng chung. Nó hoạt động và tôi cũng đồng ý với @Simon.
— Shree

6
hãy cẩn thận, có thể không có trận đấu (tức là Place == -1)
— Alireza Noori

7
Có lẽ sẽ hợp lý hơn khi trả về nguồn hơn là chuỗi trống trong trường hợp không tìm thấy kết quả phù hợp.
— Sasha

2
Bạn nên trả về "return Source;" thay vì "return sting.Empty;" bởi vì lôgic của nó không thành công nếu không tìm thấy sự xuất hiện của chuỗi Tìm.
— Jignesh Variya

1
Thêm cái này vào giữa (và chuỗi Nguồn như trong: public static string ReplaceLastOccurance(this string Source...và bạn có phương thức mở rộng tiện lợi mà bạn có thể sử dụng để thay thế lần xuất hiện cuối cùng của chuỗi cho bất kỳ chuỗi nào.
— beaudeesome

12

Sử dụng string.LastIndexOf()để tìm chỉ mục của lần xuất hiện cuối cùng của chuỗi và sau đó sử dụng chuỗi con để tìm giải pháp của bạn.


7

Bạn phải thực hiện thay thế theo cách thủ công:

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

3

Tôi không hiểu tại sao Regex không thể được sử dụng:

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

Sử dụng:

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
Bạn nên giá trị Regex.Escape ().
— jcox

Ý bạn là return Regex.Replace(Regex.Replace(source),pattern, replacement);,?
— toddmo

Giả sử ai đó gọi ReplaceEnd ("(foobar)", ")", "thenewend"). Hàm của bạn sẽ ném, vì ") $" là một regex không hợp lệ. Điều này sẽ hoạt động: return RegexReplace (nguồn, Regex.Escape (giá trị) + "$", thay thế); Câu chuyện tương tự cho RemoveEnd của bạn.
— jcox

@jcox, tôi không thể tìm ra cách tránh thoát kép, b / c mỗi hàm là công khai nên chúng tôi có nhiều đường dẫn cuộc gọi tiềm năng. Trong trường hợp của tôi, tôi không sử dụng nó cho các ký tự đặc biệt, nhưng tôi thấy ý của bạn.
— toddmo

@toddmo Tôi sẽ có ReplaceEnd và RemoveEnd gọi trực tiếp Regex.Replace. Kinda lạc đề, mặc dù; Tôi chỉ muốn mọi người lưu ý rằng việc đưa đầu vào của người dùng vào một mẫu regex có thể rất phức tạp. Tương tự như việc đưa đầu vào vào XML hoặc SQL - cần có một số cơ chế thoát.
— jcox

1

Bạn có thể sử dụng một Pathlớp từ không System.IOgian tên:

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

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

0

Giải pháp có thể được thực hiện đơn giản hơn với một dòng duy nhất:

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

Do đó, chúng tôi tận dụng sự tham lam của toán tử dấu hoa thị regex. Hàm được sử dụng như thế này:

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
Mặc dù câu trả lời chỉ có mã có thể trả lời câu hỏi, nhưng bạn có thể cải thiện đáng kể chất lượng câu trả lời của mình bằng cách cung cấp ngữ cảnh cho mã của bạn, lý do tại sao mã này hoạt động và một số tham chiếu đến tài liệu để đọc thêm. Từ Cách trả lời : "Sự ngắn gọn có thể chấp nhận được, nhưng những lời giải thích đầy đủ hơn thì tốt hơn."
— Pranav Hosangadi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.