2016-10-27 1 views
1

У меня есть вектор строк, и я просто хочу, чтобы извлечь эти значения, которые принимают формуКак использовать регулярное выражение для этого выражения (например, «6.81E + 10»)?

  1. «[цифра] [.] [Цифра] [цифра] [E] [+] [цифра] [цифра ]»или
  2. "[цифра] [] [цифра] [цифра] [E] [+] [цифра] [цифра] [цифра]"

примером может быть:.

  1. "6.81E + 10" и
  2. "5. 01E + 110"

Пусть вектор a быть следующим:

a<-c("1.23E+110", 
"1.77E+12", 
"11.22E+110", 
"1.222E+110", 
"1.22E+1", 
"1.22E+1888", 
"1..72E+18", 
"1.23EE+18", 
"1.27E++18", 
"1.27E+E+18", 
"1.27R+180") 

Моя команда:

grep("^[[:digit:]]{1}[.]{1}[[:digit:]]{2}[E+]{1}[[:digit:]]{2,3}",a,value=TRUE)

Я хотел бы его вернуть:

[1] "1.23E+110" "1.77E+12"

Но вместо этого он возвращает: character(0)

Почему он не может работать?

+2

Используйте 'grep ("^[0-9] {1} \\. [0-9] {2} E \\ + [0-9] {2,3} $ ", a) ' – Zach

+3

разделите' E' и '+' – SymbolixAU

+4

Или 'grep ("^\\ d [.] \\ d {2} E [+] \\ d {2,3} $ ", a, value = TRUE) 'в этом отношении – thelatemail

ответ

2

Ваш вопрос возникает из-за линии [E+]. Это говорит «E или +», так что вы рассказываете его искать или E или +

Кроме того, + на своих собственных средств «1 или более», так искать «+» символ, который нужно чтобы избежать этого, либо с \\+ или с использованием строкового литерала [+]

Кроме того, необходимо в конце линии якоря $ в конце регулярного выражения, поэтому он знает, что последние {2 или 3} цифры также должны быть конец строки.

Непосредственным исправление к вашему Предложенное решение является

grep("^[[:digit:]]{1}[.]{1}[[:digit:]]{2}[E][+][[:digit:]]{2,3}$",a, value = T) 
# [1] "1.23E+110" "1.77E+12" 

Но, как и другие предложили (в частности, @thelatemail), аккуратнее подход

grep("^\\d[.]\\d{2}E[+]\\d{2,3}$", a, value=TRUE) 

где \\d коротка для [:digit:]

2

/[E +]/соответствует «E» или «+», но не «E +»./x {1}/является избыточным, эквивалентным/x /. Без «$» в конце, чтобы отметить конец строки, любые конечные символы после номера допустимы./[[: digit:]]/совпадает с/[0-9]/или/\ d /.

Упростите регулярное выражение на /^\d.\d\dE +\d{2,3}$/, удваивая \ to \ для вызова строки.

2

Учитывая, что у вас несколько сложное регулярное выражение (ну, во многом, чтобы соответствовать), я буду защищать, используя rex пакет.Это действительно очень удобно для написания этой длинной regex модели в более удобном для чтения формата с использованием замещенных ярлыков и R синтаксиса:

a <- c("1.23E+110", 
     "1.77E+12", 
     "11.22E+110", 
     "1.222E+110", 
     "1.22E+1", 
     "1.22E+1888", 
     "1..72E+18", 
     "1.23EE+18", 
     "1.27E++18", 
     "1.27E+E+18", 
     "1.27R+180") 

regPat <- rex::rex(start, 
        n_times(digit, 1), 
        n_times(dot, 1), 
        n_times(digit, 2), 
        n_times("E+", 1), 
        between(digit, 2, 3), 
        end) 

regPat 
#> ^(?:[[:digit:]]){1}(?:\.){1}(?:[[:digit:]]){2}(?:E\+){1}(?:[[:digit:]]){2,3}$ 

или, если {1} значения не изменится (в соответствии с комментария) ...

regPat <- rex::rex(start, 
        digit, 
        dot, 
        n_times(digit, 2), 
        "E+", 
        between(digit, 2, 3), 
        end) 

regPat 
#> ^[[:digit:]]\.(?:[[:digit:]]){2}E\+(?:[[:digit:]]){2,3}$ 

grep(regPat, a, value = TRUE) 
#> [1] "1.23E+110" "1.77E+12" 
+0

Несомненно, 'n_times (digit, 1)' etc можно заменить просто цифрой? Как 'rex (начало, цифра, точка, n_times (цифра, 2),« E + », между (цифрой, 2, 3), конец)' – thelatemail

+0

Конечно, но я старался максимально точно воспроизвести исходную команду, и он имеет '{1}' s. В любом случае, это значительно более читаемо. –

Смежные вопросы