Заменить периоды ожидания пробелами

У меня странный запрос с регулярным выражением в R. У меня есть вектор символов, где некоторые имеют несколько периодов времени. Я хочу заменить эти периоды пробелами. Пример и желаемый результат должны четко определить, что мне нужно (возможно, мне нужно атаковать его тем, что я даю вместо аргумента аргумента, чем аргумент шаблона gsub):

Пример и попытки:

x <- c("good", "little.bad", "really.ugly......")
gsub("\\.$", " ", x)
  #produces this
  #[1] "good"              "little.bad"        "really.ugly..... "
gsub("\\.+$", " ", x)
  #produces this
  #[1] "good"         "little.bad"   "really.ugly "

Желаемый результат

[1] "good"              "little.bad"        "really.ugly      "

Итак, у исходного вектора (x) была последняя строка с 6 периодами в конце, поэтому мне хотелось бы 6 пробелов, не касаясь периода между действительно и уродливым. Я знаю, что $ смотрит в конец, но не может пройти мимо этого.

Ответ 1

Попробуйте следующее:

gsub("\\.(?=\\.*$)", " ", mystring, perl=TRUE)

Объяснение:

\.   # Match a dot
(?=  # only if followed by
 \.* # zero or more dots
 $   # until the end of the string
)    # End of lookahead assertion.

Ответ 2

Пока я ждал решения регулярного выражения, которое имеет смысл, я решил придумать бессмысленный способ решить эту проблему:

messy.sol <- function(x) {
paste(unlist(list(gsub("\\.+$", "", x), 
    rep(" ", nchar(x) -  nchar(gsub("\\.+$", "", x))))),collapse="")
}

sapply(x, messy.sol, USE.NAMES = FALSE)

Я бы сказал, что Тим немного красивее:)

Ответ 3

Решение Тима явно лучше, но я решил, что попробую свою руку поочередно. Использование либерального использования regmatches помогает нам здесь

x <- c("good", "little.bad", "really.ugly......")
# Get an object with 'match data' to feed into regmatches
# Here we match on any number of periods at the end of a string
out <- regexpr("\\.*$", x)

# On the right hand side we extract the pieces of the strings
# that match our pattern with regmatches and then replace
# all the periods with spaces.  Then we use assignment
# to store that into the spots in our strings that match the
# regular expression.
regmatches(x, out) <- gsub("\\.", " ", regmatches(x, out))
x
#[1] "good"              "little.bad"        "really.ugly      "

Так не так чисто, как одно регулярное выражение. Но я никогда не собирался изучать эти "взгляды" в регулярных выражениях perl.