2012-06-22 34 views
9

Tôi muốn thực hiện chức năng với R để xóa các ký tự lặp lại trong một chuỗi. Ví dụ, nói chức năng của tôi được đặt tên removeRS, vì vậy nó là nghĩa vụ phải làm việc theo cách này:Làm cách nào để xoá các ký tự lặp lại trong chuỗi bằng R?

removeRS('Buenaaaaaaaaa Suerrrrte') 
    Buena Suerte 
    removeRS('Hoy estoy tristeeeeeee') 
    Hoy estoy triste 

chức năng của tôi sẽ được sử dụng với chuỗi viết bằng tiếng Tây Ban Nha, vì vậy nó không phải là phổ biến mà (hoặc ít nhất là đúng) để tìm các từ có nhiều hơn ba nguyên âm kế tiếp. Không bận tâm về tình cảm có thể có đằng sau họ. Tuy nhiên, có những từ có thể có hai phụ âm kế tiếp (đặc biệt là ll và rr), nhưng chúng ta có thể bỏ qua điều này từ chức năng của chúng ta.

Vì vậy, để tổng hợp, hàm này sẽ thay thế các chữ cái xuất hiện ít nhất ba lần liên tiếp chỉ với chữ cái đó. Trong một trong các ví dụ trên, aaaaaaaaa được thay thế bằng a.

Bạn có thể cho tôi bất kỳ gợi ý nào để thực hiện tác vụ này với R không?

+0

"Tác vụ này" hiện không được chỉ định rõ ràng. Trailing các nguyên âm lặp lại có thể cần phải được xử lý khác nhau, nhưng điều này không rõ ràng từ mô tả. –

Trả lời

19

Tôi không nghĩ rất cẩn thận về vấn đề này, nhưng đây là giải pháp nhanh chóng của tôi sử dụng tài liệu tham khảo trong biểu thức thông thường :

gsub('([[:alpha:]])\\1+', '\\1', 'Buenaaaaaaaaa Suerrrrte') 
# [1] "Buena Suerte" 

() chụp một bức thư đầu tiên, \\1 đề cập đến lá thư đó, + nghĩa để phù hợp với nó một lần trở lên; đặt tất cả các mảnh lại với nhau, chúng ta có thể kết hợp một chữ cái hai hoặc nhiều lần.

Để bao gồm các ký tự khác ngoài chữ và số, hãy thay thế [[:alpha:]] bằng regex khớp với bất kỳ thứ gì bạn muốn đưa vào.

+1

Cảm ơn, nếu bạn muốn loại trừ một số chữ cái này? Ví dụ, loại trừ các chữ cái L và R. – Nestorghh

+0

'[: alpha:]' có nghĩa là 'a-zA-Z'; nếu bạn muốn cụ thể, bạn có thể nói, ví dụ: '[a-zA-KM-QS-Z]' để loại bỏ chữ hoa L và R; xem '? regexp' –

+0

Dưới đây là một biến thể sử dụng một kiểu dáng perl theo chiều rộng bằng không, ví dụ:' gsub ("([[: alpha:]]) (? = \\ 1)", "", s, perl = TRUE) '. Nó phù hợp với tất cả, nhưng cuối cùng trong bất kỳ hoạt động của các ký tự chữ cái. –

5

Tôi nghĩ bạn nên chú ý đến sự mơ hồ trong mô tả sự cố của mình. Đây là một đâm đầu tiên, nhưng rõ ràng không làm việc với "Good Luck" theo cách mà bạn mong muốn:

removeRS <- function(str) paste(rle(strsplit(str, "")[[1]])$values, collapse="") 
removeRS('Buenaaaaaaaaa Suerrrrte') 
#[1] "Buena Suerte" 
+0

Cảm ơn câu trả lời của bạn @DWin. Ví dụ với "Good Luck" không làm phiền tôi chút nào và tôi chấp nhận và xin lỗi vì sự mơ hồ. Những điều bằng tiếng Anh không hoạt động như tiếng Tây Ban Nha theo nghĩa này. Tôi đã thử giải pháp của bạn và nó hoạt động như tôi mong muốn. Nhân tiện, tôi đã chỉnh sửa câu hỏi để làm rõ hơn. – Nestorghh

0

Vì bạn muốn thay thế ký tự xuất hiện ít nhất 3 lần, đây là giải pháp của tôi:

gsub("([[:alpha:]])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
#[1] "Buenna Suertee" 

Như bạn sẽ nhìn thấy 4 "a" đã được giảm xuống chỉ 1 a, 3 r có được giảm xuống 1 r nhưng 2 n và 2 e không bị thay đổi. Như đã đề cập ở trên, bạn có thể thay thế [[:alpha:]] bởi bất kỳ sự kết hợp của [a-zA-KM-Z] hoặc tương tự, và thậm chí sử dụng "hoặc" điều hành | bên trong dấu ngoặc squre [y|Q] nếu bạn muốn mã của bạn để ảnh hưởng đến chỉ lặp đi lặp lại của y và Q.

gsub("([a|e])\\1{2,}", "\\1", "Buennaaaa Suerrrtee") 
# [1] "Buenna Suerrrtee" 
# triple r are not affected and there are no triple e. 
Các vấn đề liên quan