2009-03-30 36 views
13

Tôi cần phải tạo một regex có thể khớp với nhiều chuỗi. Ví dụ, tôi muốn tìm tất cả các trường hợp "tốt" hoặc "tuyệt vời". Tôi đã tìm thấy một số ví dụ, nhưng những gì tôi nghĩ ra dường như không hoạt động:Regex để khớp nhiều chuỗi

\b(good|great)\w*\b 

Bất cứ ai có thể chỉ cho tôi đúng hướng không?

Chỉnh sửa: Tôi nên lưu ý rằng tôi không muốn chỉ khớp toàn bộ từ. Ví dụ, tôi có thể muốn kết hợp "ood" hoặc "reat" (các phần của từ).

Chỉnh sửa 2: Đây là một số văn bản mẫu: "Đây là một câu chuyện thực sự tuyệt vời". Tôi có thể muốn khớp "this" hoặc "really" hoặc tôi có thể muốn khớp "eall" hoặc "reat".

+1

Bạn có muốn khớp "oo", "o" hoặc "t" không? – jpalecek

+3

Còn ooooooooooooooooooooooooooooooooooooooooooooooooooo? –

+0

Tôi thấy rằng việc sử dụng "tốt | tuyệt vời" khi mô hình hoạt động, điều này có ổn không? Tại sao một số ví dụ của mọi người lại có nhiều đánh dấu hơn? –

Trả lời

21

Nếu bạn có thể đảm bảo rằng không có ký tự regex dành riêng trong danh sách từ của bạn (hoặc nếu bạn thoát khỏi chúng), bạn chỉ có thể sử dụng mã này để làm cho a big word list vào @"(a|big|word|list)". Không có gì sai với toán tử | khi bạn sử dụng toán tử, miễn là () bao quanh nó. Có vẻ như là \w* và các mẫu \b là những yếu tố gây trở ngại cho các trận đấu của bạn.

String[] pattern_list = whatever; 
String regex = String.Format("({0})", String.Join("|", pattern_list)); 
+1

Có thể một lỗi: Nó phải là String.Join ("|", word_list) thay vì String.Join (word_list, "|"), xem thêm http://msdn.microsoft.com/en-us/library/57a79xd0 .aspx – David

+0

Tốt bắt - cảm ơn! Tôi đã cập nhật câu trả lời của mình. – ojrac

+1

Trái với câu hỏi, nó sẽ không khớp với ví dụ '' ood "' trong '" tốt "'. – MikeM

4
(good)*(great)* 

sau khi chỉnh sửa của bạn:

\b(g*o*o*d*)*(g*r*e*a*t*)*\b 
+0

Sẽ không phù hợp với ooooooooooooooooooooooooooooooooooooooooddddddddddddddddddddddddddddddddd? –

+0

Có, cùng với "gore", "gogogo" và một loạt các kết hợp không mong muốn khác. – Randy

0

Tôi không hiểu vấn đề một cách chính xác:

Nếu bạn muốn kết hợp "tuyệt vời" hay "reat" bạn có thể thể hiện điều này bằng một mô hình như:

"g?reat" 

Điều này đơn giản nói rằng phần "reat" phải tồn tại và "g" là tùy chọn.

Điều này phù hợp với "reat" và "great" nhưng không "ăn", bởi vì "r" đầu tiên trong "reat" là bắt buộc.

Nếu bạn có quá lời "tuyệt vời" và "tốt" và bạn muốn kết hợp cả hai với một tùy chọn "g" bạn có thể viết những dòng này như thế này:

(g?reat|g?ood) 

Và nếu bạn muốn bao gồm một ranh giới từ như:

\b(g?reat|g?ood) 

Bạn nên biết rằng điều này sẽ không khớp với bất kỳ thứ gì như "thở" vì bạn có "reat" nhưng "r" không nằm trong ranh giới từ vì "b ".

Vì vậy, nếu bạn muốn kết hợp toàn bộ từ có chứa một liên kết chuỗi "reat" hoặc "ood" thì bạn nên thử:

"\b\w*?(reat|ood)\w+\b" 

này lần đọc: 1. Bắt đầu với một ranh giới từ bắt đầu phù hợp với bất kỳ số từ-ký tự, nhưng không được gready. 2. Kết hợp "reat" hoặc "ood" đảm bảo rằng chỉ những từ phù hợp có chứa một trong số chúng. 3. Kết hợp bất kỳ số ký tự từ nào sau "reat" hoặc "ood" cho đến khi đạt đến ranh giới từ tiếp theo.

này sẽ phù hợp:

"tốt lành", "tốt", "ood" (nếu một từ hoàn chỉnh)

Nó có thể được đọc như sau: Hãy cho tôi tất cả các từ hoàn chỉnh có chứa "ood" hoặc "reat".

Đó có phải là những gì bạn đang tìm kiếm không?

1

Tôi không hoàn toàn chắc chắn rằng chỉ riêng regex cung cấp giải pháp cho những gì bạn đang cố gắng làm. Tuy nhiên, bạn có thể sử dụng đoạn mã sau để tạo biểu thức regex cho một từ đã cho. Mặc dù, mô hình regex kết quả có tiềm năng trở nên rất dài và chậm:

function wordPermutations($word, $minLength = 2) 
{ 
    $perms = array(); 

    for ($start = 0; $start < strlen($word); $start++) 
    { 
     for ($end = strlen($word); $end > $start; $end--) 
     { 
      $perm = substr($word, $start, ($end - $start)); 

      if (strlen($perm) >= $minLength) 
      { 
       $perms[] = $perm; 
      } 
     } 
    } 

    return $perms; 
} 

Kiểm tra Code:

$perms = wordPermutations('great', 3); // get all permutations of "great" that are 3 or more chars in length 
var_dump($perms); 

echo ('/\b('.implode('|', $perms).')\b/'); 

Kết quả ví dụ:

array 
    0 => string 'great' (length=5) 
    1 => string 'grea' (length=4) 
    2 => string 'gre' (length=3) 
    3 => string 'reat' (length=4) 
    4 => string 'rea' (length=3) 
    5 => string 'eat' (length=3) 

/\b(great|grea|gre|reat|rea|eat)\b/ 
1

Tôi nghĩ bạn được yêu cầu cho smth bạn không thực sự có nghĩa là nếu bạn muốn tìm kiếm bất kỳ phần nào của t anh ấy nói, bạn tìm kiếm các chữ cái một cách ngớ ngẩn

ví dụ: Tìm kiếm {Jack, Jim} trong "John và Shelly là mát mẻ"

đang tìm kiếm tất cả các chữ trong tên {J, a, c, k, i, m}

* J * Ohn * một * nd Shelly * a * tái

và cho rằng bạn không cần REG-EX :)

theo ý kiến ​​của tôi, một Suffix Tree có thể giúp bạn với điều đó

http://en.wikipedia.org/wiki/Suffix_tree#Functionality

thưởng thức.

1

Chỉ cần kiểm tra boolean rằng trả về Regex.IsMatch().

if (Regex.IsMatch(line, "condition") && Regex.IsMatch(line, "conditition2")) 

Dòng sẽ có cả regex, phải.

+0

Danh sách có thể có nhiều hơn hai từ trong đó, và cách tiếp cận này không có quy mô tốt. Ngoài ra, tôi nghĩ bạn chỉ cần khớp một trong các từ, có nghĩa là '&&' của bạn nên là '||'. Câu trả lời chính nó đã có nhiều vấn đề với định dạng, cú pháp và chính tả, mà tôi đã cố gắng sửa chữa. Vui lòng xem lại các thay đổi của tôi. –

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