2017-01-06 11 views
1

Я пытаюсь вставить символ «+» в середину почтового индекса. Почтовые индексы по шаблону AA111AA или AA11AA. Я хочу, чтобы «+» был вставлен перед окончательным номером, поэтому выход AA11+1AA или AA1+1AA. Я нашел способ сделать это, используя stringr, но похоже, что есть более простой способ сделать это так, как я это делаю сейчас. Ниже мой код.Вставка символа динамически в строку в R

pc <- "bt43xx" 

pc <- str_c(
     str_sub(pc, start = 1L, end = -4L), 
     "+", 
     str_sub(pc, start = -3L, end = -1L) 
    ) 

pc 
[1] "bt4+3xx" 

ответ

3

Вот некоторые альтернативы. Все решения работают, если pc является скаляром или вектором. Пакетов не требуется. Из них (3) кажется особенно коротким и простым.

1) Match все (.*) до последней цифры (\\d), а затем заменить, что с первым захватом (т.е. матч на часть в пределах первого набора скобок), плюс и второй захват (т.е. совпадение с последней цифрой).

sub("(.*)(\\d)", "\\1+\\2", pc) 

2) Альтернативы, которая еще короче, чтобы соответствовать цифрам, за которым следует нецифровым и заменить, что с плюсом с последующим матчем:

sub("(\\d\\D)", "+\\1", pc) 
## [1] "bt4+3xx" 

3) Это еще меньше (2). Это соответствует последним 3-х символов, заменяющие матч с плюсом с последующим матчем:

sub("(...)$", "+\\1", pc) 
## [1] "bt4+3xx" 

4) Это одно разбивает строку на отдельные символы, вставляет плюс в соответствующем положении с помощью append и помещает символы Вернуться вместе.

sapply(Map(append, strsplit(pc, ""), after = nchar(pc) - 3, "+"), paste, collapse = "") 
## [1] "bt4+3xx" 

Если pc были известны скалярная (как в случае в вопросе) она может быть упрощена:

paste(append(strsplit(pc, "")[[1]], "+", nchar(pc) - 3), collapse = "") 
[1] "bt4+3xx" 
1

Это регулярное выражение с sub и двумя обратными ссылками должно работать.

sub("(\\d?)(\\d[^\\d]*)$", "\\1+\\2", pc) 
[1] "bt4+3xx" 
  • \\ д? соответствует 1 или 0 числовым символам, 0-9, и фиксируется(). Он будет соответствовать, если присутствует хотя бы два числовых символа.
  • \\ d [^ \\ d] * соответствует числовому символу с последующим всех не цифровыми символами, и захватываются()
  • $ анкеров регулярного выражения к концу строки
  • «\\ 1 + \\ 2 "заменяет согласованные элементы в первых двух точках с самим собой и" + "в середине.
+1

Это не выпирал потребность OP в качестве + после цифры. Я бы сделал 'sub (" (. *) (\\ d \\ D {2}) "," \\ 1 + \\ 2 ", pc)' – Haboryme

+0

Ugh. Я пропустил это. Спасибо за уловку. – lmo