Как заменить одиночный / двойной символ в строке

Я хочу заменить все одиночные символы в моей строке пробелом. Моя идея заключается в том, что должен быть пробел до и после одного символа. Так что я поставил пробелы до и после персонажа, но это не сработало. Я также хотел заменить строку более чем на 1 символ. То есть, если я хочу заменить все символы длиной 2 или около того, как изменится код.

str="I have a cat of white color"
str=gsub("([[:space:]][[a-z]][[:space:]])", "", str)

2 ответа

Решение

Вам необходимо использовать свойство регулярного выражения квантора, например: [a-z]{2} который соответствует буквам a в z дважды вместе. Шаблон регулярного выражения, который вы хотите, выглядит примерно так:

\\s[a-z]{2}\\s

Вы можете динамически построить это регулярное выражение в R, используя введенное количество символов. Вот фрагмент кода, который демонстрирует это:

str <- "I have a cat of white color"
nchars <- 2
exp <- paste0("\\s[a-z]{", nchars, "}\\s")

> gsub(exp, "", str)
[1] "I have a catwhite color"

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

Идея не верна, слово не всегда окружено пробелами. Что, если слова находятся в начале строки? Или в конце? Или сопровождается пунктуацией?

использование \b граница слова:

Есть три разных положения, которые квалифицируются как границы слов:
- перед первым символом в строке, если первый символ является символом слова.
- После последнего символа в строке, если последний символ является символом слова.
- Между двумя символами в строке, где один является символом слова, а другой не является символом слова.

Обратите внимание, что в R, когда вы используете gsubлучше всего использовать с регулярным выражением PCRE (pass perl=T):

POSIX 1003.2 режим gsub а также gregexpr неправильно работает с повторяющимися границами слов (например, pattern = "\b"). использование perl = TRUE для таких совпадений (но это может не работать должным образом с входными данными, не относящимися к ASCII, поскольку значение слова зависит от системы).

Таким образом, чтобы соответствовать всем 1-буквенным словам, вам нужно использовать

gsub("(?i)\\b[a-z]\\b", "REPLACEMENT", input, perl=T) ## To replace 1 ASCII letter words

Обратите внимание, что (?i) является регистронезависимым модификатором (создание a соответствовать обоим a а также A).

Теперь вам нужно сопоставить 2 буквенные слова:

gsub("(?i)\\b[a-z]{2}\\b", "REPLACEMENT", input, perl=T) ## To replace 2 ASCII letter words

Здесь мы используем ограничивающий квантификатор {min, max} / {max} чтобы указать, сколько раз образец, количественно определенный с помощью этой конструкции, может быть повторен.

Смотрите демоверсию IDEONE:

> input = "I am a football fan"
> gsub("(?i)\\b[a-z]\\b", "REPLACEMENT", input, perl=T) ## To replace 1 ASCII letter words
[1] "REPLACEMENT am REPLACEMENT football fan"
gsub("(?i)\\b[a-z]{2}\\b", "REPLACEMENT", input, perl=T) ## To replace 2 ASCII letter words
[1] "I REPLACEMENT a football fan"
Другие вопросы по тегам