Làm cách nào để thay thế * trường hợp đầu tiên * của một chuỗi trong .NET?


108

Tôi muốn thay thế lần xuất hiện đầu tiên trong một chuỗi nhất định.

Làm cách nào để thực hiện điều này trong .NET?


Hãy làm rõ ràng bài viết để mọi người có thể hiểu được. Tôi cũng đã chỉnh sửa cái này cho bạn. Bạn nên chỉ định một ngôn ngữ ít nhất ở đây.
GEOCHET

Tất nhiên, nó không bao giờ được thay thế ... nó luôn là một chuỗi mới chứa chuỗi gốc với văn bản được thay thế. Điều này là do chuỗi là bất biến.
Pablo Marambio

tôi đã thử phương thức `String.Replace ()`. nhưng nó thay thế tất cả "AA" bằng "XQ"
Thorin Oakenshield

2
câu hỏi này - stackoverflow.com/questions/141045/… - tiết lộ mọi thứ về những gì bạn cần làm
stack72

1
Lưu ý: kết hợp với một câu hỏi tương tự khác đã sử dụng "AA" => "XQ" làm ví dụ để tìm / thay thế.
Marc Gravell

Câu trả lời:


134
string ReplaceFirst(string text, string search, string replace)
{
  int pos = text.IndexOf(search);
  if (pos < 0)
  {
    return text;
  }
  return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}

Thí dụ:

string str = "The brown brown fox jumps over the lazy dog";

str = ReplaceFirst(str, "brown", "quick");

CHỈNH SỬA : Như @itsmatt đã đề cập , còn có Regex.Replace (Chuỗi, Chuỗi, Int32), có thể làm tương tự, nhưng có lẽ đắt hơn trong thời gian chạy, vì nó sử dụng trình phân tích cú pháp đầy đủ tính năng trong đó phương thức của tôi thực hiện một tìm và ba chuỗi nối.

EDIT2 : Nếu đây là một tác vụ phổ biến, bạn có thể muốn đặt phương thức này thành một phương thức mở rộng:

public static class StringExtension
{
  public static string ReplaceFirst(this string text, string search, string replace)
  {
     // ...same as above...
  }
}

Sử dụng ví dụ trên, bây giờ có thể viết:

str = str.ReplaceFirst("brown", "quick");

2
Thật thú vị, bạn đã kiểm tra giả định của mình về cách tiếp cận regex đắt hơn trong thời gian chạy chưa? Làm thế nào về tốc độ? Có lẽ tìm kiếm bằng Regex nhanh hơn sử dụng IndexOf?
mfloryan

Tôi thích câu trả lời của @BilltheLizard liên quan đến Remove () và Insert () hơn cách tiếp cận này liên quan đến Substring (). Có cơ sở nào để nói cái này tốt hơn cái kia không?
JohnC

3
Lưu ý: Điều này không hoạt động đúng với Unicode kết hợp các ký tự hoặc chữ ghép. Ví dụ: ReplaceFirst("oef", "œ", "i")trả về "ief" thay vì "if" không chính xác. Xem câu hỏi này để biết thêm thông tin.
Michael Liu,

2
ReSharper cảnh báo String.IndexOf is culture specific.. Mạnh mẽ hơn để cập nhật lên int pos = text.IndexOf(search, StringComparison.Ordinal);.
Contango

64

Như itmatt đã nói Regex.Replace là một lựa chọn tốt cho việc này, tuy nhiên để làm cho câu trả lời của anh ấy hoàn thiện hơn, tôi sẽ điền vào nó bằng một mẫu mã:

using System.Text.RegularExpressions;
...
Regex regex = new Regex("foo");
string result = regex.Replace("foo1 foo2 foo3 foo4", "bar", 1);             
// result = "bar1 foo2 foo3 foo4"

Tham số thứ ba, được đặt thành 1 trong trường hợp này, là số lần xuất hiện của mẫu regex mà bạn muốn thay thế trong chuỗi đầu vào từ đầu chuỗi.

Tôi đã hy vọng điều này có thể được thực hiện với quá tải Regex.Replace tĩnh nhưng rất tiếc, có vẻ như bạn cần một phiên bản Regex để thực hiện nó.


1
Điều đó phù hợp với nghĩa đen "foo", nhưng bạn sẽ muốn có nghĩa new Regex(Regex.Escape("foo"))bóng "foo".
ruffin


15

Có tính đến "chỉ đầu tiên", có lẽ:

int index = input.IndexOf("AA");
if (index >= 0) output = input.Substring(0, index) + "XQ" +
     input.Substring(index + 2);

?

Hay nói chung:

public static string ReplaceFirstInstance(this string source,
    string find, string replace)
{
    int index = source.IndexOf(find);
    return index < 0 ? source : source.Substring(0, index) + replace +
         source.Substring(index + find.Length);
}

Sau đó:

string output = input.ReplaceFirstInstance("AA", "XQ");

11
using System.Text.RegularExpressions;

RegEx MyRegEx = new RegEx("F");
string result = MyRegex.Replace(InputString, "R", 1);

sẽ tìm thấy đầu tiên Ftrong InputStringvà thay thế nó bằng R.


2
Tôi đơn giản hóa nó đến một lớp lót bằngresult = (New Regex("F")).Replace(InputString, "R", 1)
cjbarth

Câu trả lời hay nhất ở đây (kết hợp với cjbarth)
Todd Vance

8

Phương thức mở rộng C # sẽ thực hiện việc này:

public static class StringExt
{
    public static string ReplaceFirstOccurrence(this string s, string oldValue, string newValue)
    {
         int i = s.IndexOf(oldValue);
         return s.Remove(i, oldValue.Length).Insert(i, newValue);    
    } 
}

Thưởng thức


Cảm ơn! Tôi đã sửa đổi điều này để tạo một phương thức mở rộng "RemoveFirst" ... loại bỏ sự xuất hiện đầu tiên của một ký tự khỏi một chuỗi.
pbh101 11/02/09

4
Điều này sẽ không thành công nếu oldValue không phải là một phần của chuỗi.
VVS

8

Trong cú pháp C #:

int loc = original.IndexOf(oldValue);
if( loc < 0 ) {
    return original;
}
return original.Remove(loc, oldValue.Length).Insert(loc, newValue);

4

Và bởi vì cũng có VB.NET để xem xét, tôi muốn đưa ra:

Private Function ReplaceFirst(ByVal text As String, ByVal search As String, ByVal replace As String) As String
    Dim pos As Integer = text.IndexOf(search)
    If pos >= 0 Then
        Return text.Substring(0, pos) + replace + text.Substring(pos + search.Length)
    End If
    Return text 
End Function

4

Giả sử rằng AAchỉ cần được thay thế nếu nó nằm ở đầu chuỗi:

var newString;
if(myString.StartsWith("AA"))
{
  newString ="XQ" + myString.Substring(2);
}

Nếu bạn cần thay thế lần xuất hiện đầu tiên của AA, cho dù chuỗi bắt đầu bằng nó hay không, hãy sử dụng giải pháp từ Marc.


3

Một trong những quá tải của Regex.Replacenhận là int"Số lần thay thế tối đa có thể xảy ra". Rõ ràng, việc sử dụng Regex.Replaceđể thay thế văn bản thuần túy có vẻ quá mức cần thiết, nhưng nó chắc chắn ngắn gọn:

string output = (new Regex("AA")).Replace(input, "XQ", 1);

2

Đối với bất kỳ ai không ngại tham chiếu đến Microsoft.VisualBasic, có ReplacePhương pháp :

string result = Microsoft.VisualBasic.Strings.Replace("111", "1", "0", 2, 1); // "101"

1

Ví dụ này tóm tắt các chuỗi con (nhưng chậm hơn), nhưng có lẽ nhanh hơn nhiều so với RegEx:

var parts = contents.ToString().Split(new string[] { "needle" }, 2, StringSplitOptions.None);
return parts[0] + "replacement" + parts[1];

-1
string abc = "AAAAX1";

            if(abc.IndexOf("AA") == 0)
            {
                abc.Remove(0, 2);
                abc = "XQ" + abc;
            }
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 cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.