Выделите только последнюю часть строки после последней точки - PullRequest
1 голос
/ 15 апреля 2019

У меня есть датафрейм с одним столбцом, который представляет запросы, сделанные моими пользователями. Несколько примеров выглядят так:

GET /enviro/html/tris/tris_overview.html
GET /./enviro/gif/emcilogo.gif
GET /docs/exposure/meta_exp.txt.html
GET /hrmd/
GET /icons/circle_logo_small.gif

Я хочу выбрать только последнюю часть строки после последней "." таким образом, что я возвращаю тип страницы строки. Выходные данные этих строк должны быть:

.html
.gif
.html

.gif

Я попытался сделать это с помощью sub, но мне удается выбрать все только после первого "." Пример:

tring <- c("GET /enviro/html/tris/tris_overview.html", "GET /./enviro/gif/emcilogo.gif", "GET /docs/exposure/meta_exp.txt.html", "GET /hrmd/", "GET /icons/circle_logo_small.gif")


sub("^[^.]*", "", sapply(strsplit(tring, "\\s+"), `[`, 2))

это возвращает:

".html"                     
"./enviro/gif/emcilogo.gif" 
".txt.html"                 
""                          
".gif"  

Я создал следующий код gsub, который работает для строки, содержащей две точки:

gsub(pattern = ".*\\.", replacement = "", "GET /./enviro/gif/finds.gif", "\\s+")

это возвращает:

"gif"

Тем не менее, я не могу придумать один gsub / sub, который работает для всех возможных вводов. Следует читать строку справа налево. Остановись, когда увидит первый "." и вернуть все, что было найдено после этого "."

Я новичок в R и не могу придумать что-то, что делает это. Любая помощь будет принята с благодарностью!

Ответы [ 2 ]

2 голосов
/ 15 апреля 2019

Вы не можете изменить направление разбора строки с помощью R regex. Вместо этого вы можете сопоставить все до . и удалить его или сопоставить ., у которого нет символов . справа от него до конца строки.

string <- c('GET /enviro/html/tris/tris_overview.html','GET /./enviro/gif/emcilogo.gif','GET /docs/exposure/meta_exp.txt.html','GET /hrmd/','GET /icons/circle_logo_small.gif')
res <- regmatches(string, regexec("\\.[^.]*$", string))
res[lengths(res)==0] <- ""
unlist(res)

Или

sub("^(.*(?=\\.)|.*)", "", string, perl=TRUE)

См. Онлайн-демонстрацию R . Оба возвращают

[1] ".html" ".gif"  ".html" ""      ".gif"

Здесь \.[^.]*$ соответствует ., а затем любым 0+ символам, кроме ., до конца строки. В коде sub используется шаблон ^(.*(?=\\.)|.*), который соответствует началу строки, затем либо любые 0+ символов до . без использования точки, либо просто соответствуют любым 0+ символам, насколько это возможно, и заменяет совпадение с пустой строкой.

См. Regex 1 и Regex 2 demos.

0 голосов
/ 15 апреля 2019

Вот решение без регулярных выражений:

sapply(
  seq_along(a),
  function(i) {
    if (grepl("\\.", a[i])) tail(strsplit(a[i], "\\.")[[1]], 1) else ""
  }
)

# [1] "html" "gif"  "html" ""     "gif" 
...