2015-01-23 19 views
18

Sử dụng C#, tôi có một chuỗi là tập lệnh SQL chứa nhiều truy vấn. Tôi muốn loại bỏ các phần của chuỗi được kèm theo trong dấu nháy đơn. Tôi có thể làm điều này bằng Regex.Replace, theo cách này:Làm thế nào để loại bỏ chỉ một số chất nền từ một chuỗi?

string test = "Only 'together' can we turn him to the 'dark side' of the Force"; 
test = Regex.Replace(test, "'[^']*'", string.Empty); 

Kết quả trong: "Chỉ có chúng ta có thể biến anh ta đến của Force"

Những gì tôi muốn làm là loại bỏ các chuỗi con giữa dấu ngoặc kép EXCEPT cho các đoạn có chứa một chuỗi con cụ thể. Ví dụ: sử dụng chuỗi ở trên, tôi muốn xóa các phần tử được trích dẫn ngoại trừ các đoạn có chứa "tối", sao cho chuỗi kết quả là:

Kết quả trong: "Chỉ chúng ta có thể biến anh ta thành 'tối side 'of the Force'

Làm cách nào để thực hiện điều này bằng cách sử dụng Regex.Replace hoặc có thể bằng một số kỹ thuật khác? Tôi hiện đang thử một giải pháp có liên quan đến việc sử dụng Substring(), IndexOf()Contains().

Lưu ý: Tôi không quan tâm liệu dấu nháy đơn xung quanh "mặt tối" có bị xóa hay không, do đó kết quả cũng có thể là: "Chỉ chúng ta mới có thể biến anh ta thành mặt tối của Lực lượng." Tôi nói điều này vì giải pháp sử dụng Split() sẽ xóa tất cả các dấu nháy đơn.

Edit: Tôi không có một giải pháp được nêu sử dụng Substring(), IndexOf(), vv Bằng cách "làm việc trên:" Tôi có nghĩa là tôi đang nghĩ trong đầu tôi như thế nào điều này có thể được thực hiện. Tôi không có mã, đó là lý do tại sao tôi chưa đăng bất kỳ mã nào. Cảm ơn.

Chỉnh sửa: Giải pháp của VKS bên dưới hoạt động. Tôi đã không thoát khỏi \ b nỗ lực đầu tiên, đó là lý do tại sao nó thất bại. Ngoài ra, nó không hoạt động trừ khi tôi bao gồm các dấu nháy đơn xung quanh toàn bộ chuỗi.

test = Regex.Replace(test, "'(?![^']*\\bdark\\b)[^']*'", string.Empty); 
+13

@AndyKorneyev Điều gì khiến bạn nghĩ đây không phải là cách hay để đặt câu hỏi ở đây? Đây là một trong những bài viết đầu tiên hoàn chỉnh hơn tôi đã thấy trong một thời gian. Có một nỗ lực tốt, với regex, vấn đề được làm rõ, có một vài ý tưởng, tôi không thực sự thấy làm thế nào điều này có thể có thể tốt hơn, ít bao gồm cả câu trả lời thực tế. –

+7

@AndyKorneyev Op của hai dòng mã của mình cho thấy nỗ lực của mình phải không? Ngoài ra câu hỏi được viết tốt và cho thấy nỗ lực nghiên cứu rất tốt. –

+2

@SriramSakthivel rằng hai dòng không phải là về OP muốn. Đó là về một số "nhiệm vụ sơ bộ". Nhưng nỗ lực thực sự chỉ được mô tả là "* Tôi hiện đang thử một giải pháp liên quan đến việc sử dụng Substring(), IndexOf() và Contains(). *" Mà không hiển thị bất kỳ mã nào. –

Trả lời

21
'(?![^']*\bdark\b)[^']*' 

Hãy thử this.See demo.Replace bởi empty string .Bạn có thể sử dụng lookahead đây để kiểm tra xem '' chứa một từ dark.

https://www.regex101.com/r/rG7gX4/12

+0

Đó là một trang web tuyệt vời, nhưng tôi không thể làm cho nó hoạt động trong ứng dụng C# của tôi. Tôi đã sử dụng tính năng "trình tạo mã" và sao chép nó, nhưng nó không có bất kỳ tác dụng nào trên chuỗi. Tôi sẽ cần phải đọc thêm về Regex để hiểu cú pháp đủ tốt để dịch nó tôi nghĩ. Cảm ơn! – armus47

+0

Điều đó hoạt động! Sắp xếp, tôi vẫn phải bao gồm các dấu nháy đơn bao quanh toàn bộ chuỗi regex mà bạn bỏ qua trong nhận xét của mình. Tôi sẽ đặt nó vào bài viết của tôi. Cảm ơn – armus47

+6

@ armus47 tốt hơn nên sử dụng chuỗi nguyên văn trong trường hợp này, vì vậy bạn không phải thoát khỏi các dấu gạch chéo ngược: 'Regex.Replace (test, @" '(?! [^'] * \ Bdark \ b) [^'] *' ", string.Empty)' –

4

một số điều như thế này sẽ hiệu quả.
bạn có thể thêm tất cả các chuỗi bạn muốn giữ lại vào mảng excludedStrings

 string test = "Only 'together' can we turn him to the 'dark side' of the Force"; 

     var excludedString = new string[] { "dark side" }; 

     int startIndex = 0; 

     while ((startIndex = test.IndexOf('\'', startIndex)) >= 0) 
     { 
      var endIndex = test.IndexOf('\'', startIndex + 1); 
      var subString = test.Substring(startIndex, (endIndex - startIndex) + 1); 
      if (!excludedString.Contains(subString.Replace("'", ""))) 
      { 
       test = test.Remove(startIndex, (endIndex - startIndex) + 1); 
      } 
      else 
      { 
       startIndex = endIndex + 1; 
      } 
     } 
+2

Đây là cách tiếp cận mà tôi có trong đầu khi tôi không thể nhờ Regex làm việc. Tôi ấn tượng bởi việc bạn nhanh chóng kết hợp điều đó với nhau như thế nào. Cảm ơn! – armus47

16

Trong khi giải pháp VKS của công trình, tôi muốn chứng minh một cách tiếp cận khác nhau:

string test = "Only 'together' can we turn him to the 'dark side' of the Force"; 
test = Regex.Replace(test, @"'[^']*'", match => { 
    if (match.Value.Contains("dark")) 
     return match.Value; 

    // You can add more cases here 

    return string.Empty; 
}); 

Hoặc, nếu tình trạng của bạn là đơn giản đủ:

test = Regex.Replace(test, @"'[^']*'", match => match.Value.Contains("dark") 
    ? match.Value 
    : string.Empty 
); 

Tức là, sử dụng lambda để gọi lại để thay thế. Bằng cách này, bạn có thể chạy logic tùy ý để thay thế chuỗi.

+1

Điều này hoạt động hoàn hảo và là câu trả lời tôi đang tìm kiếm. Tôi không thể có được giải pháp của vks để làm việc, nhưng đó là một trang web khá tiện lợi. Giải pháp của Vignesh là cách tiếp cận mà tôi đang cố gắng giải quyết mà không sử dụng Regex. Nhưng tôi thích giải pháp này bởi vì nó sử dụng Regex và logic bổ sung cho một cách tiếp cận dễ hiểu. Cảm ơn! – armus47

1

Tôi đã thực hiện nỗ lực này mà tôi nghĩ bạn đang nghĩ đến (một số giải pháp sử dụng split, Contain, ...không có regex)

string test = "Only 'together' can we turn him to the 'dark side' of the Force"; 
string[] separated = test.Split('\''); 

string result = ""; 

for (int i = 0; i < separated.Length; i++) 
{ 
    string str = separated[i]; 
    str = str.Trim(); //trim the tailing spaces 

    if (i % 2 == 0 || str.Contains("dark")) // you can expand your condition 
    { 
     result += str+" "; // add space after each added string 
    } 
} 
result = result.Trim(); //trim the tailing space again 
1

Phương thức khác thông qua nhà điều hành thay thế regex |.

@"('[^']*\bdark\b[^']*')|'[^']*'" 

Sau đó thay thế các nhân vật phù hợp với $1

DEMO

string str = "Only 'together' can we turn him to the 'dark side' of the Force"; 
string result = Regex.Replace(str, @"('[^']*\bdark\b[^']*')|'[^']*'", "$1"); 
Console.WriteLine(result); 

IDEONE

Giải thích:

  • (...) được gọi là capturing group.

  • '[^']*\bdark\b[^']*' sẽ khớp với tất cả các chuỗi được trích dẫn có chứa chuỗi con dark. [^']* khớp với bất kỳ ký tự nào nhưng không phải là ', không hoặc nhiều lần.

  • ('[^']*\bdark\b[^']*'), vì regex là trong một nhóm chụp, tất cả các ký tự tương ứng được lưu trữ bên trong chỉ số nhóm 1.

  • | Tiếp đến regex alternation operator.

  • '[^']*' Bây giờ này phù hợp với tất cả các còn lại (trừ một chứa dark) chuỗi trích dẫn duy nhất. Lưu ý rằng điều này sẽ không khớp với chuỗi được trích dẫn duy nhất chứa chuỗi con dark vì chúng tôi đã khớp các chuỗi đó với mẫu trước khi đến toán tử luân phiên |.

  • Cuối cùng, thay thế tất cả các ký tự phù hợp bằng ký tự bên trong chỉ mục nhóm 1 sẽ cung cấp cho bạn kết quả mong muốn.

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