2008-10-28 42 views
18

Tôi đang cố gắng viết cụm từ thông dụng thay thế để bao quanh tất cả các từ trong dấu ngoặc kép ngoại trừ các từ AND, OR và NOT.Regex phù hợp với tất cả các từ ngoại trừ một danh sách nhất định

Tôi đã thử những điều sau đây cho phần phù hợp của biểu thức:

(?i)(?<word>[a-z0-9]+)(?<!and|not|or) 

(?i)(?<word>[a-z0-9]+)(?!and|not|or) 

nhưng không phải làm việc. Biểu thức thay thế rất đơn giản và hiện bao quanh tất cả các từ.

"${word}" 

Vì vậy

này và này không Đó

trở thành

"Đây" và "Đây" không phải là "That"

+0

Bạn có thể cung cấp đầu vào mẫu và kết quả mong đợi (khớp hay không)? – mohammedn

+0

(? I) (? [a-z0-9] ++) (?

Trả lời

14

này là một chút bẩn, nhưng nó hoạt động:

(?<!\b(?:and| or|not))\b(?!(?:and|or|not)\b) 

Trong tiếng Anh đơn giản, điều này phù hợp với bất kỳ ranh giới từ không phải do và không tiếp theo là "và", "hoặc", hoặc "không". Nó chỉ đối sánh với toàn bộ các từ, ví dụ: vị trí sau từ "cát" sẽ không phù hợp chỉ vì nó được bắt đầu bằng "và".

Không gian phía trước "hoặc" trong xác nhận phía sau có chiều rộng bằng không là cần thiết để làm cho nó có chiều dài cố định phía sau. Hãy thử nếu điều đó đã giải quyết được vấn đề của bạn.

EDIT: Áp dụng cho chuỗi "ngoại trừ các từ AND, OR và NOT". thay thế toàn cầu bằng dấu nháy đơn, điều này trả về:

'except' 'the' 'words' AND, OR and NOT. 
+0

Tình huống duy nhất mà điều này có thể thất bại là khi chuỗi bắt đầu bằng từ "hoặc". Được rồi, và nó chứa giả định ẩn rằng không gian tách biệt các từ của bạn. Cả hai tình huống có thể được di chuyển nếu bạn biết dữ liệu của bạn. – Tomalak

+0

Như với tất cả các regex, nó là điên, nhưng nó hoạt động. (? [a-z0-9] +) ( John

+0

Bạn cần gì "( [a- z0-9] +) "cho? Bạn đang cố gắng để bao quanh từ của bạn với dấu ngoặc kép hoặc bạn đang cố gắng để nhổ chúng ra khỏi chuỗi? – Tomalak

3

Gọi cho tôi là điên, nhưng tôi không phải là người hâm mộ chiến đấu; Tôi hạn chế mô hình của tôi để mọi thứ đơn giản tôi có thể hiểu, và thường gian lận cho phần còn lại - ví dụ thông qua một MatchEvaluator:

string[] whitelist = new string[] { "and", "not", "or" }; 
    string input = "foo and bar or blop"; 
    string result = Regex.Replace(input, @"([a-z0-9]+)", 
     delegate(Match match) { 
      string word = match.Groups[1].Value; 
      return Array.IndexOf(whitelist, word) >= 0 
       ? word : ("\"" + word + "\""); 
     }); 

(sửa cho bố trí ngắn gọn hơn)

+1

Tôi gọi bạn là điên. :-P – Tomalak

+1

@Tomalak: Touché –

+0

Thật không may nó là dot net 2 vì vậy không có lambda chỉ – John

2

Dựa trên Tomalaks câu trả lời:

regex này có hai vấn đề:

  1. (?<!) chỉ hoạt động với chiều dài cố định nhìn phía sau

  2. Regex trước chỉ xem kết thúc/đầu của các từ xung quanh chứ không phải toàn bộ từ.

(?<!\band)(?<!\bor)(?<!\bnot)\b(?!(?:and|or|not)\b)

này regex sửa cả những vấn đề trên. Đầu tiên bằng cách chia cái nhìn đằng sau thành ba cái riêng biệt. Thứ hai bằng cách thêm từ-ranh giới (\b) bên trong các giao diện.

5

John,

Regex trong câu hỏi của bạn gần như chính xác. Vấn đề duy nhất là bạn đặt lookahead vào cuối regex thay vì lúc bắt đầu. Ngoài ra, bạn cần thêm các ranh giới từ để buộc regex khớp với toàn bộ các từ. Nếu không, nó sẽ khớp với "thứ hai" trong "và", "r" trong "hoặc", v.v. bởi vì "thứ hai" và "r" không có trong cái nhìn tiêu cực của bạn.

\ b (i?) (Và |?! Không | hay) (? [A-z0-9] +) \ b

+0

Có, mọi người khác đang làm điều này phức tạp hơn nhiều so với nhu cầu của nó. Đặc biệt, không cần tiêu cực (hoặc tích cực, cho rằng vấn đề) lookbehinds hoặc đặt tên được chụp. –

+0

Hai điều: đầu tiên, tôi đã đi đến kết luận rằng specifiying một chữ '[az]' trong một regex thay vì '\ pL' hoặc' \ p {Alphabetic} 'hoặc đôi khi' [[: alpha:]] ' hầu như luôn luôn là "những năm 1960" ở tuổi hậu 7 ‐ bit của chúng tôi. Thứ hai, tôi thấy mọi người [thường hiểu lầm những gì \ b thực sự] (http://stackoverflow.com/questions/4213800/is-there-something-like-a-counter-variable-in-regular-expression-replace/4214173 # 4214173), vì vậy gần đây tôi đã thêm provisos vào gotchas của nó bất cứ khi nào tôi khuyên bạn nên nó. (Vâng, tôi biết rằng * bạn * tất nhiên hiểu tất cả điều này, Jan, nhưng nhiều độc giả có lẽ không.) – tchrist

0
(?!\bnot\b|\band\b|\bor\b|\b\"[^"]+\"\b)((?<=\s|\-|\(|^)[^\"\s\()]+(?=\s|\*|\)|$)) 

tôi sử dụng regex này để tìm tất cả các từ không nằm trong dấu ngoặc kép hoặc là các từ "không" và "hoặc" hoặc "."

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