2015-08-05 12 views
5

Tôi đang cố gắng phân tích một ngày từ một chuỗi văn bản. Tôi giả sử cách tốt nhất để làm điều này là regex, nhưng tôi đã không hoàn toàn tìm thấy một giải pháp hoạt động.Ngày phân tích theo định dạng Thứ Hai, DD, YYYY bằng cách sử dụng RegEx trong R

Trước tiên, tôi đã sử dụng bộ chọn CSS để lấy ngày từ một trang web.

date <-html_nodes(x=doc, css=".middleheadline+ .topnewsbar b") %>% html_text() 

này tạo ra:

[1] "\r\n  Washington,\r\n  Jan 5, 2011" 

tôi muốn trích xuất từ ​​ngày bản thân (ở đây, ngày 05 tháng 1 2011) từ chuỗi này. LƯU Ý: tháng có thể là bất kỳ tháng nào, ngày có thể là bất kỳ ngày nào và năm có thể là bất kỳ điều gì từ 2011-2015, vì vậy tôi đang cố gắng tìm một biểu thức có thể phân tích cú pháp một ngày trong Ngày D [D], Định dạng YYYY.

Dưới đây là một nỗ lực:

date <-str_extract_all(string=date, pattern='[A-Z][a-z]{3,4} ([0-9]{1,2}), [0-9]{4}') 

này tạo character(0)

Và khác:

grep("[A-Z][a-z]{3,4} ([0-9]{1,2}), [0-9]{4}", date, value=TRUE) 

mà cũng sản xuất character(0)

Bất cứ lời khuyên?

+0

có lẽ 'grep (" \\ w {3,4} \\ d {1,2}, \\ d {4}, ngày, giá trị = TRUE) 'Tôi chưa thử nghiệm điều này. Thẻ w' sẽ khớp với các ký tự alpha, thẻ '\\ d' khớp với các chữ số. – Benjamin

+1

Ngày luôn ở cuối chuỗi hay luôn luôn sau" '\ r \ n" '? –

+0

cuối cùng Tôi đồng ý với ý nghĩa của Joshua chúng ta cần thêm thông tin về ý nghĩa của dữ liệu đầu vào - không chỉ ngày tháng trông như thế nào. Việc chuyển đổi sang một loại ngày thực tế đủ dễ dàng miễn là chúng ta có thể xác định đầu vào. Và nếu nó luôn ở cuối chuỗi đầu vào sau đó làm cho nó * thực sự * dễ dàng – Dason

Trả lời

2

Bạn có thể thử này: link

date <-str_extract_all(string=date, pattern='\\w+\\s\\d+(st)?(nd)?(rd)?(th)?,\\s+\\d+') 

HERE thử nghiệm.

+0

Cảm ơn Richard Scriven, bây giờ nó sẽ hoạt động – teoreda

+1

Cảm ơn! Tôi đã phải thêm dấu gạch chéo kép để làm cho nó hoạt động: 'ngày <-str_extract_all (chuỗi = ngày, mẫu = '\\ w + \\ s \\ d + (st)? (Nd)? (Rd)? (Th) ?, \\ s + \\ d + ') ' –

+0

Tôi đã chỉnh sửa bài đăng @RachelB. :) – teoreda

2

Một chức năng để chuyển đổi các ngày:

make_dates <- function(x, date_format=TRUE, split="\n") { 
    dates <- lapply(strsplit(x, split), function(x) { 
    grep("\\w+ \\d+, \\d+", x, value=T)}) 

    if(date_format) { 
    strptime(gsub("\\s", "", dates), format="%b%d,%Y") 
    } else { gsub(".*?(\\w.*)", "\\1", dates)} 
} 

test <- c("\r\n  Washington,\r\n  Jan 5, 2011", 
     "\r\n  Boston,\r\n  Mar 15, 2015") 

make_dates(test) 
#[1] "2011-01-05 EST" "2015-03-15 EDT" 
make_dates(test, FALSE) 
#[1] "Jan 5, 2011" "Mar 15, 2015" 
5

Bạn cũng có thể thử strsplit(). Đôi khi tôi thích nó hơn một biểu hiện thường xuyên tâm-numbing.

test <- c("\r\n  Washington,\r\n  Jan 5, 2011", 
    "\r\n  Boston,\r\n  Mar 15, 2015") 

vapply(strsplit(test, ".*\n\\s+"), "[", "", 2) 
# [1] "Jan 5, 2011" "Mar 15, 2015" 

as.Date(vapply(strsplit(test, ".*\n\\s+"), "[", "", 2), "%b %d, %Y") 
# [1] "2011-01-05" "2015-03-15" 
1

Đây là một regex sẽ trả về ngày trong chuỗi ở nhiều định dạng MDY khác nhau, với nhiều dải phân cách. Đảm bảo đặt tùy chọn case insensitve trong quy trình của bạn.

Nó thực hiện một số kiểm tra lỗi thô sơ, nhưng nó sẽ cho phép hai năm chữ số; và cũng sẽ cho phép một ngày như Feb 31, 2015

\b((?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)[a-z]*|(?:0?[1-9]|1[0-2]))(?:\s*([- /.])\s*)(?:(0?[1-9]|[12]\d|3[01])(?:st|nd|rd|th)?),?\2((?:19|2\d)?\d{2})\b 
0

Tôi nghĩ rằng đây sẽ là đủ:

[A-Z][a-z]{2} \d{1,2}, 201[1-4] 

Demo: https://regex101.com/r/eW3jV6/1

tháng Có gì viết tắt là dài 5 hoặc 4 ký tự? Regex của bạn không thành công vì bạn có [A-Z][a-z]{3,4} cho biết ký tự chữ hoa và sau đó là ba hoặc bốn ký tự chữ thường. Tôi không quen với một tháng có chữ viết tắt gồm 5 ký tự.

Chuỗi của bạn Jan dài 3 ký tự nhưng chỉ 2 trong số đó là chữ thường.

Demo của regex hiện tại của bạn: https://regex101.com/r/bJ6gT3/1

Nếu có một khả năng của nhiều khoảng trống giữa tháng và ngày và/hoặc năm thêm trong \h+; hoặc nếu không có không gian, hãy làm cho nó \h*.

+0

Một số ngày sử dụng từ viết tắt 3 char, trong khi những cái khác là tên tháng đầy đủ (từ 4 đến 9 ký tự). Tôi đang cố gắng tìm một cái gì đó sẽ đối phó với tất cả các hoán vị của tên tháng. –

+0

Bạn có thể sử dụng nhóm một cái gì đó như '(Jan (uary)? | Feb (urary)? | Mar (ch)?)' Vv .. sau đó kiểm tra ngày và năm. – chris85

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