2012-03-01 29 views
9

Tôi gặp sự cố với regex của mình để nắm bắt các từ được viết hoa liên tiếp. Dưới đây là những gì tôi muốn regex để nắm bắt:Nhận các từ được viết hoa liên tiếp bằng cách sử dụng regex

"said Polly Pocket and the toys" -> Polly Pocket 

Đây là regex Tôi đang sử dụng:

re.findall('said ([A-Z][\w-]*(\s+[A-Z][\w-]*)+)', article) 

Nó trả về như sau:

[('Polly Pocket', ' Pocket')] 

tôi muốn nó trở lại :

['Polly Pocket'] 
+0

Vậy nếu đầu vào là ' tôi có một chuỗi và nó dài? Nó có nên cho '['có một chuỗi', 'Nó là dài']' hay '['có một chuỗi và nó dài']' –

+0

Tại sao bạn có từ "đã nói" trong tìm kiếm của bạn? Bạn có thực sự có ý định chỉ tìm các từ vốn liên tiếp sau "đã nói" không? – jgritty

Trả lời

23

Sử dụng tích cực nhìn về phía trước:

([A-Z][a-z]+(?=\s[A-Z])(?:\s[A-Z][a-z]+)+) 

Khẳng định rằng từ hiện tại, để được chấp nhận, cần phải được theo sau bởi một từ khác với một chữ cái viết hoa trong đó. Chia nhỏ:

(    # begin capture 
    [A-Z]   # one uppercase letter \ First Word 
    [a-z]+   # 1+ lowercase letters/
    (?=\s[A-Z])  # must have a space and uppercase letter following it 
    (?:    # non-capturing group 
    \s    # space 
    [A-Z]   # uppercase letter \ Additional Word(s) 
    [a-z]+   # lowercase letter /
)+    # group can be repeated (more words) 
)    #end capture 
+0

Điều này vẫn cho '['Polly Pocket', 'Pocket']' khi tôi chạy nó. –

+0

@Adam: Đã phải làm với nhóm nội bộ cũng chụp. Hãy chạy những gì tôi có ngay bây giờ, đăng phần bổ sung phân tích. –

+0

Và một +1 lớn cho bạn tốt sir. :) –

6

Đó là vì findall trả về tất cả các nhóm chụp trong regex của bạn, và bạn có hai nhóm chụp (một trong đó được tất cả các văn bản phù hợp, và bên trong một cho những lời tiếp theo).

Bạn chỉ có thể làm cho nhóm chụp thứ hai của bạn vào một tổ chức phi chụp từng người sử dụng (?:regex) thay vì (regex):

re.findall('([A-Z][\w-]*(?:\s+[A-Z][\w-]*)+)', article) 
+0

Tôi không nghĩ rằng 'nói' được dự định là một phần của regex. Tức là: 'anh ấy thích Polly Pocket' nên trả lại những trận đấu giống nhau. –

+0

oh xin lỗi, tôi đã sao chép một cách mù quáng từ OP. –

4
$mystring = "the United States of America has many big cities like New York and Los Angeles, and others like Atlanta"; 

@phrases = $mystring =~ /[A-Z][\w'-]\*(?:\s+[A-Z][\w'-]\*)\*/g; 

print "\n" . join(", ", @phrases) . "\n\n# phrases = " . scalar(@phrases) . "\n\n"; 

OUTPUT:

$ ./try_me.pl 

United States, America, New York, Los Angeles, Atlanta 

\# phrases = 5 
Các vấn đề liên quan