удалить не цифры, кроме E + и E- в строке - PullRequest
0 голосов
/ 22 декабря 2018

У меня есть вектор vec, который я хочу преобразовать в числовой тип.Поэтому мне нужно сначала избавиться от нецифровых цифр (включая «+»).Проблема: Когда я исключаю их, также удаляются символы «+» и «-» из символов «E +» и «E-».

Как я могу удалить все нецифровые символы, кроме «E-», 'E +' и '.'от vec?

vec = c('1234', '+ 42', '1E+4', 'NR 12', '4.5E+04', '8.6E-02')

Мои подходы:

gsub('[^0-9E.]', '', vec) # removes '-' and '+' in 'E-' and 'E+'

gsub('[^0-9(E\\+).]', '', vec) # includes the '+' from '+ 42' 

Мой желаемый результат:

c('1234', '42', '1E+4', '12', '4.5E+04', '8.6E-02')

Ответы [ 6 ]

0 голосов
/ 22 декабря 2018

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

library(tidyverse)
library(stringr)

vec <- c('1234', '+ 42', '1E+4', 'NR 12', '4.5E+04', '8.6E-02')

vec %>%
  str_extract_all("(\\+|\\-)*[:digit:]+(\\.)?[:digit:]*", simplify = TRUE) %>%
  apply(2, as.numeric) %>%
  as_tibble() %>%
  mutate(V2 = ifelse(is.na(V2), 0, V2)) %>%
  mutate(result = V1*10^V2)

Результат:

# A tibble: 6 x 3
      V1    V2    result
   <dbl> <dbl>     <dbl>
1 1234       0  1234    
2   42       0    42    
3    1       4 10000    
4   12       0    12    
5    4.5     4 45000    
6    8.6    -2     0.086

... затем .$result, конечно.

0 голосов
/ 22 декабря 2018

Вы не можете сопоставить ни одной цифры, пока не встретите число:

^\D+(?=(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)?)

Это будет соответствовать:

  • ^ Начало строки
  • \D+ соответствует 1+ раз, а не цифре
  • (?= Положительный прогноз
    • (?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[eE][+-]?[0-9]+)? Совпадение числа или десятичного числа с E или e
  • ) Закрыть позитивный прогноз

Например:

vec = c('1234', '+ 42', '1E+4', 'NR 12', '4.5E+04', '8.6E-02')
print(gsub('^\\D+(?=(?:[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+)(?:[eE][+-]?[0-9]+)?)', '', vec, perl=TRUE))
# [1] "1234"    "42"      "1E+4"    "12"      "4.5E+04" "8.6E-02"

Regex demo | R демо

0 голосов
/ 22 декабря 2018

Вы можете извлечь числа, используя после следующего регулярного выражения :

[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?

Подробности

  • [-+]? - либо +, либо -
  • [0-9]* - 0+ цифр
  • \.? - необязательно .
  • [0-9]+ -1+ цифры
  • ([eE][-+]?[0-9]+)? - дополнительная группа захвата (добавьте ?: после (, чтобы использовать группу без захвата), соответствующие 1 или 0 вхождениям
    • [eE] -e или E
    • [-+]? - необязательно - или +
    • [0-9]+ - 1 или более цифр

R demo :

vec <- c('1234', '+ 42', '1E+4', 'NR 12', '4.5E+04', '8.6E-02')
res <- regmatches(vec, regexpr("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?", vec))
unlist(res)
## => [1] "1234"    "42"      "1E+4"    "12"      "4.5E+04" "8.6E-02"

Если ожидается несколько совпадений на элемент в символьном векторе, замените regexpr на gregexpr.

0 голосов
/ 22 декабря 2018

Вы можете изменить свое регулярное выражение, чтобы проверить, не предшествует ли + или - E или e, и в этом случае не удалять их (используя оглядку назад и включить perl = TRUE), а в противном случае, включите + и - в свой основной набор символов, чтобы в любом другом случае они были удалены с пустой строкой.Попробуйте изменить строку с

gsub('[^0-9E.]', '', vec)

на

gsub('(?<![Ee])[+-]|[^0-9E.+-]', '', vec, perl=TRUE)
0 голосов
/ 22 декабря 2018

В качестве альтернативы, в базе R и с gsub:

gsub("\\D.* ", "", vec)
0 голосов
/ 22 декабря 2018

Ну, это работает:

str_remove_all(vec,"\\D.* ")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...