Замените все слово, которое начинается с шаблона, используя gsub в R - PullRequest
0 голосов
/ 04 мая 2018

У меня проблемы с проблемой, которую так просто решить. Я хотел бы заменить целые слова в строке, которые начинаются с шаблона.

> test <- "i really wasn aware and i wasnt aware at all. but i wasn't aware. just wasn't."

    ## this is what i want
    > output
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't."

лучший из всех, с кем я пришел, это

# this is what get, but it's not correct
> gsub("\\<wasn*.\\>", "wasn't", test)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't't aware. Just wasn't't."

У меня действительно заканчиваются идеи. Я также был бы счастлив с

 # second desired output without the . at the end
    > output
    [1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't"

Редактировать: кажется, мой вопрос был слишком конкретным. Итак, я добавляю другие тестовые случаи. По сути, я не знаю, за какими символами следуют слова «разве», и я хотел бы преобразовать все в не

> test <- "i really wasn aware and i wasnt aware at all. but i wasn't aware. just wasn't. this wasn45'e meant to be. it wasn@'re simple"
> test
[1] "i really wasn aware and i wasnt aware at all. but i wasn't aware. just wasn't. this wasn45'e meant to be. it wasn@'re simple"

#desired output
> output
 [1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't. this wasn't meant to be. it wasn't simple"

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Я предлагаю решение, подобное этому:

test <- c("i really wasn aware and i wasnt aware at all. but i wasn't aware. just wasn't. this wasn45'e meant to be. it wasn@'re simple", "Wasn&^$tt that nice?", "You say wasnmmmt?", "No, he wasn&#t#@$.", "She wasn%#@t##, I know.")
 gsub("\\b(wasn)\\S*\\b(?:\\S*(\\p{P})\\B)?", "\\1't\\2", test, ignore.case=TRUE, perl=TRUE)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't. this wasn't meant to be. it wasn't simple"
[2] "Wasn't that nice?"                                                                                                          
[3] "You say wasn't?"                                                                                                            
[4] "No, he wasn't."                                                                                                             
[5] "She wasn't, I know." 

См. онлайн R демо .

Это решение учитывает случаи, когда wasn* появляется в начале строки или пишется с большой буквы и не заменяет конечную пунктуацию.

Детали шаблона

  • \\b - граница слова
  • (wasn) - Группа захвата 1 (позднее обозначается \\1 в шаблоне замены): подстрока wasn (без учета регистра из-за ignore.case=TRUE)
  • \\S*\\b - любые 0+ символов, кроме пробелов, за которыми следует граница слова
  • (?:\\S*(\\p{P})\\B)? - необязательная группа без захвата, соответствующая 1 или 0 вхождениям
    • \\S* - 0+ непробельных символов
    • (\\p{P}) - Группа захвата 2 (позднее обозначается \\2 в шаблоне замены): любая 1 пунктуация (не символ! \p{P} не равна [:punct:]!), За которой не следует символ .. .
    • \\B - буква, цифра или _ (это шаблон, не состоящий из слов).

Для еще более сложных строк (например, She wasn%#@t##,$#^ I know.), когда знаки препинания могут находиться внутри других символов пунктуации, вы можете ограничить пунктуацию, на которой вы хотите остановиться, используя пользовательское выражение в скобках и добавив \S* в конце:

gsub("\\b(wasn)\\S*\\b(?:\\S*([?!.,:;])\\S*)?", "\\1't\\2", test, ignore.case=TRUE, perl=TRUE)

См. Демоверсию regex .

0 голосов
/ 04 мая 2018

Почему бы не сделать это простым и заменить любое слово, начинающееся с wasn, на wasn't?

test2 <- paste0(
  "i really wasn aware and i wasnt aware at all. but i wasn't aware. just",
  "wasn't. this wasn45'e meant to be. it wasn@'re simple"
)
gsub("wasn[^ ]*", "wasn't", test2)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't this wasn't meant to be. it wasn't simple"

Если вы имеете дело с прописными буквами, то вы можете просто добавить ignore.case = TRUE в gsub ().

0 голосов
/ 04 мая 2018

Вы можете использовать отрицательный взгляд вперед, предоставленный perl .. pattern=wasn(?!')t*

gsub("wasn(?!')t*","wasn't",test,perl=T)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't."

или вы можете сделать:

gsub("wasn'*t*","wasn't",test)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't."

Для второго желаемого выхода:

gsub("wasn'*t*[.]?","wasn't",test)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't"

ПОСЛЕ РЕДАКТИРОВАНИЯ:

gsub("wasn[^. ]*","wasn't",test)
[1] "i really wasn't aware and i wasn't aware at all. but i wasn't aware. just wasn't. this wasn't meant to be. it wasn't simple"
...