2012-03-07 21 views
6

Tôi cần phải thay thế một số phần của chuỗi bằng nhau bằng C#. Tôi chỉ có thể tìm thấy một câu hỏi tương tự về cách đạt được điều này here nhưng đó là PHP.Làm thế nào để thay thế hai hoặc nhiều chuỗi với nhau?

tình tôi liên quan đến một từ điển [string, string] nắm giữ cặp để thay thế như:

  • chó, mèo
  • mèo, chuột,
  • chuột, chim

Và Tôi có một chuỗi có giá trị là:

"My dog ate a cat which once ate a mouse got eaten by a raptor" 

Tôi cần một chức năng để có được điều này:

"My cat ate a mouse which once ate a raptor got eaten by a raptor" 

Nếu tôi liệt kê các từ điển và gọi string.Replace theo lệnh, tôi có được điều này:

"My raptor ate a raptor which once ate a raptor got eaten by a raptor" 

Đó là lạ nếu điều này đã không được hỏi trước , (Đó là kiến ​​thức phổ biến?) Nhưng tôi không thể tìm thấy bất kỳ. Vì vậy, tôi xin lỗi nếu nó có và tôi bị mất nó.

+0

Cách bẩn để làm điều đó là sử dụng một số văn bản trung gian. Vì vậy, chuyển đổi 'chó' thành '1', 'mèo' thành '2', và sau đó thực hiện lần truyền thứ hai, nơi bạn chuyển đổi '1' và '2' thành những gì bạn muốn. Hãy chắc chắn để sử dụng một cái gì đó độc đáo hơn so với '1' và '2' (có lẽ là một GUID). Như tôi đã nói, nó bẩn thỉu, và tôi chắc chắn có một cách tốt hơn. – xbonez

+0

Bạn muốn (làm đầu ra) cho từ điển {"foo": "1", "bar": "2", "foobar": "3"} và nhập "foo bar foobarbar" như thế nào? – Dogbert

+0

@Dogbert "1 2 32" –

Trả lời

9

Vì vậy, những gì bạn cần là cho quá trình khớp với chỉ diễn ra một lần. Đối với một lần tôi nghĩ rằng câu trả lời đúng là thực sự 'sử dụng regex'! Dưới đây là một số mã:

var replacements = new Dictionary<string, string> 
         { 
          { "do|g", "cat" }, 
          { "ca^t", "mouse" }, 
          { "mo$$use", "raptor" } 
         }; 

var source = "My do|g ate a ca^t which once ate a mo$$use"; 

var regexPattern = 
    "(" + 
    string.Join("|", replacements.Keys.Select(Regex.Escape)) + 
    ")"; 

var regex = new Regex(regexPattern); 

var result = regex.Replace(source, match => replacements[match.Value]); 

// Now result == "My cat ate a mouse which once ate a raptor" 

Mẫu chúng tôi tạo ở đây trông giống như (dog|cat|mouse). Mỗi phần trong cấu trúc xen kẽ này (|) được chuyển qua Regex.Escape, để các ký tự có ý nghĩa regex trong các phím (chẳng hạn như |, ^, v.v.) không gây ra sự cố. Khi tìm thấy kết quả phù hợp, văn bản khớp được thay thế bằng giá trị tương ứng trong từ điển. Chuỗi chỉ được quét một lần, do đó, không có sự trùng khớp lặp lại nào là vấn đề với số lần lặp lại string.Replace.

+0

Tốt hơn và thanh lịch hơn các giải pháp của tôi. +1 từ tôi. –

+1

Cảm ơn câu trả lời của bạn. Nó thực sự là thanh lịch nhưng vì tôi không có kinh nghiệm với regex; Tôi phải hỏi: Nếu tôi cố gắng thay thế chó bằng ca | t thì sao? Có cách nào để trung hòa các bộ phận tôi muốn thay thế (như dấu gạch chéo ngược và "|" nhân vật) và tránh xây dựng một cái gì đó như '(con chó | ca | t | chuột)'? –

+0

@ d4wn xem xét tuyệt vời. Đã chỉnh sửa trong việc sử dụng 'Regex.Escape' khi cần thiết. – AakashM

1

Điều bạn muốn là có tất cả các thay thế chuỗi được thực hiện đồng thời, để bạn không nhận được một số thay thế trên cùng một mã thông báo, phải không?

tôi có thể nghĩ đến hai cách tiếp cận, không phải đặc biệt thanh lịch:

  • lặp trên từ điển của bạn theo thứ tự cụ thể, vì vậy bạn sẽ luôn luôn thay thế chuột/Raptor trước mèo/chuột.
  • Thay vì thay thế mèo bằng 'chuột', hãy thay thế bằng '$ mouse $' hoặc điểm đánh dấu tương tự. Điều này sẽ đảm bảo rằng '$ mouse $' không được thay thế bằng 'raptor' (hoặc, thực sự, '$ raptor $'). Sau đó, khi bạn đã hoàn tất công tắc, bạn có thể xóa tất cả các dấu hiệu '$'.
+0

Đối với một điểm bạn sẽ cần phải thay thế theo thứ tự ngược lại của các câu hỏi, chuột -> raptor sau đó cat -> chuột sau đó chó -> mèo. – TheLukeMcCarthy

+0

Trong mẫu cụ thể này, có. Đối với một giải pháp tổng quát hơn, bạn cần phải xây dựng một số loại đồ thị theo chu kỳ trực tiếp để đảm bảo. –

+0

đó là chính xác Tôi chỉ muốn đưa ra một ví dụ cụ thể để d4wn có thể thấy lý do tại sao nó không hoạt động trước đây. – TheLukeMcCarthy

Các vấn đề liên quan