删除字符串中除E +和E-以外的非数字

时间:2018-12-22 16:08:11

标签: r regex

我有一个要转换为数字类型的向量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 :(得分:3)

您可以使用following regex 提取数字:

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

详细信息

  • [-+]?-+-
  • [0-9]*-0位数以上
  • \.?-可选的.
  • [0-9]+-1个以上数字
  • ([eE][-+]?[0-9]+)?-可选的捕获组(在?:之后添加(以使用非捕获组),匹配1次或0次匹配
    • [eE]-eE
    • [-+]?-可选的-+
    • [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

答案 1 :(得分:2)

您可以更改正则表达式以检查+-之前是否没有Ee,在这种情况下,请不要删除它们(使用后向并启用perl = TRUE),否则,请在您的主字符集中包含+-,以便在其他情况下使用空字符串将其删除。尝试从此更改行,

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

gsub('(?<![Ee])[+-]|[^0-9E.+-]', '', vec, perl=TRUE)

答案 2 :(得分:2)

在遇到数字之前,您不能匹配数字:

^\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"

Using positive-lookahead (?=regex) with re2 | Regex demo

答案 3 :(得分:1)

这可行:

str_remove_all(vec,"\\D.* ")

答案 4 :(得分:1)

或者,以R为底,并带有gsub

gsub("\\D.* ", "", vec)

答案 5 :(得分:0)

您提到您想要一个数字结果,但是您将所需的输出表示为字符输出(我忽略了这一点,只使用了数字)。

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