2013-03-27 17 views
21

Tôi muốn chia chuỗi bằng cách sử dụng hàm Split trong lớp Regex. Vấn đề là nó loại bỏ các dấu phân cách và tôi muốn giữ chúng. Tốt hơn là các phần tử riêng biệt trong phần nhỏ.Làm thế nào để giữ các dấu phân cách của Regex.Split?

Theo số other discussions mà tôi đã tìm thấy, chỉ có những cách bất tiện để đạt được điều đó.

Mọi đề xuất?

+6

chuỗi đầu vào? regex của bạn? dự kiến ​​đầu ra? – I4V

+0

'.etc' này không cung cấp nhiều thông tin. về thuật toán của bạn nhưng tôi có thể thử ít nhất. Xem câu trả lời của tôi – I4V

+6

Tại sao bạn trở nên hung hãn? Chỉ cần hỏi một câu hỏi qood và nhận được câu trả lời tốt hơn. Những gì bạn muốn làm có thể được thực hiện ngay cả khi không có 'Regex.Split'. Xem [this] (http://www.perlmonks.org/?node=xy+problem) và đọc lại câu trả lời của tôi. – I4V

Trả lời

59

Chỉ cần đặt mẫu vào chụp nhóm, và các trận đấu cũng sẽ được đưa vào kết quả.

string[] result = Regex.Split("123.456.789", @"(\.)"); 

Kết quả:

{ "123", ".", "456", ".", "789" } 

này cũng làm việc cho nhiều ngôn ngữ khác:

  • Javascript: "123.456.789".split(/(\.)/g)
  • Python: re.split(r"(\.)", "123.456.789")
  • Perl: split(/(\.)/g, "123.456.789")

(Không Java dù)

+0

Ồ, điều này thậm chí còn tốt hơn! Ví dụ thú vị - bạn khớp với * bất kỳ * nào theo một khoảng thời gian ** thực ** là một khoảng thời gian. 1 cho một cú pháp tuyệt vời! Tuy nhiên, vì lý do nào đó, nó không bắt được phần tử cuối cùng vì vậy tôi nhận được những gì bạn nói nhưng ** ngoại trừ ** cho phần * 789 *. –

+0

Trong khi đọc cái nhìn về phía trước, tôi đọc rằng nó không được đưa vào kết quả như: Regex.Match ("nói 25 dặm hơn", @ "\ d + \ s (= dặm)?"); // OUTPUT: 25 và một tuyên bố khác tuyên bố rằng để bao gồm dấu phân cách trong khi chia nhỏ bọc mẫu theo hướng tích cực phía trước như: Regex.Split ("oneTwoThree", @ "(? = [A-Z])"); // OUTPUT một Hai Ba nhầm lẫn –

+1

@sortednoun Cái nhìn phía trước khớp với 0 ký tự, chỉ khi cơ thể khớp với vị trí đó. Cơ thể nhìn phía trước không phải là một phần của trận đấu, vì vậy không có gì thêm để bao gồm. Văn bản được so khớp bởi nội dung sẽ được bao gồm trong mục mảng tiếp theo, khi chia tách. '(? = ([A-Z]))' cả hai sẽ tạo một mục bổ sung với chữ cái VÀ bao gồm nó trong mục tiếp theo. –

0

Thêm lại họ:

string[] Parts = "A,B,C,D,E".Split(','); 
    string[] Parts2 = new string[Parts.Length * 2 - 1]; 
    for (int i = 0; i < Parts.Length; i++) 
    { 
     Parts2[i * 2] = Parts[i]; 
     if (i < Parts.Length - 1) 
      Parts2[i * 2 + 1] = ","; 
    } 
+1

Nhưng điều đó không có tác dụng trong trường hợp regex có nhiều hơn một kết quả phù hợp. – AJMansfield

+1

Bạn sẽ làm gì nếu bạn không biết dấu phân cách nào được sử dụng? Bạn có thể lặp lại ví dụ cho chúng tôi * Lớp Regex * không? –

6

Sử dụng Matches để tìm các thiết bị tách trong chuỗi, sau đó nhận được các giá trị và các thiết bị tách.

Ví dụ:

string input = "asdf,asdf;asdf.asdf,asdf,asdf"; 

var values = new List<string>(); 
int pos = 0; 
foreach (Match m in Regex.Matches(input, "[,.;]")) { 
    values.Add(input.Substring(pos, m.Index - pos)); 
    values.Add(m.Value); 
    pos = m.Index + m.Length; 
} 
values.Add(input.Substring(pos)); 
+0

Ồ, tôi hiểu rồi. Mát mẻ. Tuy nhiên, tôi ước rằng sẽ có thêm một * Split * có một bool để quyết định xem nó có nên giữ các dấu phân tách hay không. Tôi đoán tôi sẽ phải bắt đầu viết mã. Cảm ơn! 1 cho một câu trả lời rõ ràng. –

3

Nói rằng đầu vào là "abc1defg2hi3jkl" và regex là để chọn ra chữ số.

String input = "abc1defg2hi3jkl"; 
var parts = Regex.Matches(input, @"\d+|\D+") 
      .Cast<Match>() 
      .Select(m => m.Value) 
      .ToList(); 

Phụ sẽ là: abc1defg2hi3jkl

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