Есть ли более короткий способ извлечения даты из строки?

Я написал код для извлечения даты из заданной строки. Учитывая

  > "Date: 2012-07-29, 12:59AM PDT"

он извлекает

  > "2012-07-29" 

Проблема заключается в том, что мой код выглядит длинным и громоздким для чтения. Мне было интересно, был ли более элегантный способ сделать это.

  raw_date = "Date: 2012-07-29, 12:59AM PDT"

  #extract the string from raw date
  index = regexpr("[0-9]{4}-[0-9]{2}-[0-9]{2}", raw_date) #returns 'start' and 'end' to be used in substring

  start = index #start represents the character position 's'. start+1 represents '='
  end = attr(index, "match.length")+start-1
  date = substr(raw_date,start,end); date

Ответ 1

Вы можете использовать strptime() для анализа объектов времени:

R> strptime("Date: 2012-07-29, 11:59AM PDT", "Date: %Y-%m-%d, %I:%M%p", tz="PDT")
[1] "2012-07-29 11:59:00 PDT"
R> 

Обратите внимание, что я переместил вашу входную строку, поскольку я не уверен, что существует 12:59 AM... Чтобы доказать точку, сдвинутую на три часа (выраженная в секундах, базовые единицы):

R> strptime("Date: 2012-07-29, 11:59AM PDT", 
+>          "Date: %Y-%m-%d, %I:%M%p", tz="PDT") + 60*60*3
[1] "2012-07-29 14:59:00 PDT"
R> 

О, и если вы просто хотите дату, это, конечно, еще проще:

R> as.Date(strptime("Date: 2012-07-29, 11:59AM PDT", "Date: %Y-%m-%d"))
[1] "2012-07-29"
R> 

Ответ 2

Что-то вроде этого должно работать:

x <- "Date: 2012-07-29, 12:59AM PDT"
as.Date(substr(x, 7, 16), format="%Y-%m-%d")

Ответ 3

Как и в большинстве случаев, у вас есть несколько вариантов. Хотя ни один из них не освобождает вас от привыкания к основному синтаксису регулярных выражений (или его близким друзьям).

raw_date <- "Date: 2012-07-29, 12:59AM PDT"

Альтернатива 1

> gsub(",", "", unlist(strsplit(raw_date, split=" "))[2])
[1] "2012-07-29"

Альтернатива 2

> temp <- gsub(".*: (?=\\d?)", "", raw_date, perl=TRUE)
> out <- gsub("(?<=\\d),.*", "", temp, perl=TRUE)
> out
[1] "2012-07-29"

Альтернатива 3

> require("stringr")
> str_extract(raw_date, "\\d{4}-\\d{2}-\\d{2}")
[1] "2012-07-29"

Ответ 4

Regex с обратными ссылками:

> sub("^.+([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]).+$","\\1","Date: 2012-07-29, 12:59AM PDT")
[1] "2012-07-29"

Но @Dirk прав, что синтаксический анализ его как даты - правильный путь.