2016-10-25 60 views
2

說我有四個文件的目錄:正則表達式過濾,然後確定最後日期

someText.abcd.xyz.10Sep16.csv 
someText.xyz.10Sep16.csv 
someText.abcd.xyz.23Oct16.csv 
someText.xyz.23Oct16.csv 

這是名稱的格式設置。我不能改變它們,格式將保持不變,除了日期會改變。所有名字都以someText開頭。接下來,有四個字母的代碼(abcd)或三個後面的代碼(xyz)。如果文件名有四個字母的代碼,那麼它後面總是會有一個三個字母的代碼。最後有一個日期值。

我有兩個任務。首先,我需要篩選出具有「abcd」組件的文件。這將始終是名稱中的someText.之後出現的四字符代碼。有沒有辦法糾正正則表達式來刪除這些值?

剩下的兩個文件:

someText.xyz.10Sep16.csv 
someText.xyz.23Oct16.csv 

我只需要與日後的文件。有沒有第二個正則表達式可以提取日期,找到最新的,然後只保留這個日期?我這樣做是爲了獲得文件設置爲四種:

myDir <- "\\\\myDir\\folder\\" 
files <- list.files(path = myDir, pattern = "\\.csv$") 

下面是與文件名的載體,如果有人想嘗試一下:

files <- c("someText.abcd.xyz.10Sep16.csv", "someText.xyz.10Sep16.csv", "someText.abcd.xyz.23Oct16.csv", "someText.xyz.23Oct16.csv") 

回答

2

這是我的一個簡單的基礎R答案

# regex subset 
files <- files[!grepl("^.*?\\.[[:alpha:]]{4}\\.", files)] 

# get date 
dates <- unlist(lapply(strsplit(files, "\\."), "[[", 3)) 

files[which.max(as.Date(dates, format = "%d%b%y"))] 
# [1] "someText.xyz.23Oct16.csv" 
嘗試
1

我想這應該是足夠強大可靠地工作。我使用dplyr來傳遞結果並對其進行操作,並使用lubridate進行方便的日期提取(dmy)。幾乎忘記了:你需要加載magrittr來獲得%$%管道。

我用「。」分隔文件名,如果缺少四個字母的代碼部分,則滑過結果。將它們綁定到data.frame中,以便輕鬆過濾等。在這裏,對那些缺少四個字母部分的人進行篩選,然後選擇具有最新日期的人。

strsplit(files, "\\.") %>% 
    setNames(files) %>% 
    lapply(function(x){ 
    if(length(x) == 4){ 
     x[3:5] <- x[2:4] 
     x[2] <- "noCode" 
    } 
    rbind(x) %>% 
     as.data.frame() 
    }) %>% 
    bind_rows(.id = "fileName") %>% 
    mutate(date = dmy(V4)) %>% 
    filter(V2 == "noCode") %$% 
    c(fileName[which.max(date)]) 

回報: 「someText.xyz.23Oct16.csv」

1

我相信,這是可以做得更緊湊,但這裏是一個基礎R回答:

# file names 
file_names =c(
    "someText.abcd.xyz.10Sep16.csv", 
    "someText.xyz.10Sep16.csv", 
    "someText.abcd.xyz.23Oct16.csv", 
    "someText.xyz.23Oct16.csv" 
) 

# the pattern to be tested 
reg_file_names = regexec(
    pattern = "^someText\\.[a-z]{4}\\.[a-z]{3}\\.(.*).csv$", 
    file_names 
) 

# parse out the matched dates, and look for the maximum 
file_names[ 
    which.max(
    sapply(
     regmatches(
     x = file_names, m = reg_file_names 
    ), 
     function(match) { 
     as.Date(
      ifelse(
      length(match) == 0, 
      NA, 
      match[2] 
     ), 
      format = "%d%b%y" 
     ) 
     } 
    ) 
) 
    ] 

常規您需要的表達式非常簡單,其餘代碼僅用於處理沒有匹配的情況,並對日期進行格式化以便進行比較。