Вставка дефиса или тире в вектор строки в зависимости от расположения конкретных элементов

Дана string vector vecA:

vecA <- c("Population 1222",
          "Population 90over",
          "population under78",
          "population 99101",
          "Population 1254", 
          "Population 78 92")

Проблема

Я хотел бы получить vecB, который будет соответствовать:

vecB <- c("Population 12 - 22",
          "Population 90 over",
          "population under 78",
          "population 99 - 101",
          "Population 12 - 54", 
          "Population 78 - 92")

Ключевые характеристики

vecB имеет следующие характеристики:

  • После первых двух цифр вставляются пробел, тире и пробел (-)
  • Если пробел существует, вставляется только тире (-)
  • Для таких комбинаций, как underDigitDigit, вставляется только пробел: under DigitDigit

Попытки

Я подумывал использовать группы в gsub, на линиях:

gsub("^([[:alpha:]]*[[:blank:]])(\\d{2})(.*)$", "\\2", vecA)

но это не работает для всех случаев:

> t(t(gsub("^([[:alpha:]]*[[:blank:]])(\\d{2})(.*)$", "\\2", vecA)))
     [,1]                
[1,] "12"                
[2,] "90"                
[3,] "population under78"
[4,] "99"                
[5,] "12"                
[6,] "78" 

t() применяется только в презентационных целях; ссылка на регулярное выражение 101.


person Konrad    schedule 03.02.2016    source источник


Ответы (1)


Вот мое предложение - сделайте это в два этапа: 1) сначала добавьте дефис между числами, а затем 2) добавьте пробел между словами "над"/"под" и числом:

vecA <- c("Population 1222",
           "Population 90over",
           "population under78",
           "population 99101",
           "Population 1254", 
           "Population 78 92")
v <- gsub("^([[:alpha:]]+[[:blank:]]+)([[:digit:]]{2})\\s*([[:digit:]])", "\\1\\2 - \\3", vecA)
gsub("^([[:alpha:]]+[[:blank:]]+)(?|(over|under)(\\d+)|(\\d+)(over|under))", "\\1\\2 \\3", v, perl=T)

Вывод демонстрационного кода:

[1] "Population 12 - 22"  "Population 90 over"  "population under 78"
[4] "population 99 - 101" "Population 12 - 54"  "Population 78 - 92"

Второе регулярное выражение содержит шаблон сброса ветвей (?|...|...), чтобы сохранить те же идентификаторы групп в альтернативных подшаблонах, поэтому требуется perl=T.

person Wiktor Stribiżew    schedule 03.02.2016