này tương tự như một trong những Learning Perl bài tập. Bí quyết là để bắt tất cả các từ lặp đi lặp lại, vì vậy bạn cần một "một hoặc nhiều" lượng hóa trên sự trùng lặp:
$str = 'This is Goethe the the the their sentence';
$str =~ s/\b((\w+)(?:\s+\2\b)+)/[\1]/g;
Các tính năng tôi về để sử dụng được mô tả trong hai perlre, khi họ áp dụng tại một mẫu hoặc perlop khi chúng ảnh hưởng đến cách toán tử thay thế thực hiện công việc của nó.
Nếu bạn thích /x
cờ để thêm khoảng trắng và bình luận không đáng kể:
$str =~ s/
\b
(
(\w+)
(?:
\s+
\2
\b
)+
)
/[\1]/xg;
Tôi không thích điều đó \2
mặc dù bởi vì tôi ghét đếm vị trí tương đối. Tôi có thể sử dụng backreferences tương đối trong Perl 5.10.Các \g{-1}
đề cập đến nhóm chụp ngay trước:
use 5.010;
$str =~ s/
\b
(
(\w+)
(?:
\s+
\g{-1}
\b
)+
)
/[\1]/xg;
Đếm không phải là tất cả những gì tuyệt vời trong hai, vì vậy tôi có thể sử dụng các trận đấu được dán nhãn:
use 5.010;
$str =~ s/
\b
(
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
)
/[\1]/xg;
tôi có thể gắn nhãn chụp đầu tiên ($1
) và truy cập vào giá trị của nó trong %+
sau:
use 5.010;
$str =~ s/
\b
(?<dups>
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
)
/[$+{dups}]/xg;
Tôi không thực sự cần chụp lần đầu tiên mặc dù nó thực sự chỉ là ở đây để chỉ mọi thứ phù hợp. Đáng buồn thay, có vẻ như ${^MATCH}
không được đặt sớm để tôi sử dụng nó ở mặt thay thế. Tôi nghĩ đó là một lỗi. Điều này sẽ hoạt động nhưng không hoạt động:
$str =~ s/
\b
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
/[${^MATCH}]/pgx; # DOESN'T WORK
Tôi đang kiểm tra lỗi này nhưng sẽ mất một chút thời gian để biên dịch trên máy nhỏ xíu của tôi.
Nguồn
2010-03-24 17:02:43
'$ str = ~ s/\ b (? (\ W +) (: \ s + \ 2) +) \ b/[\ 1]/g;' để khớp với bất kỳ số lần lặp lại nào –
@briandfoy: ... đó chính xác là câu hỏi được yêu cầu, trước khi bạn thay đổi nó. Và Eric đăng trong một bình luận một phiên bản phù hợp với nhiều hơn một lần lặp lại. – Kip
@brian: Làm thế nào để bạn biết rằng từ 2 dòng ngữ cảnh trong câu hỏi gốc? –