Как сопоставить все, кроме цифр с пробелом и ТОЛЬКО цифр с пробелом? - PullRequest
0 голосов
/ 23 апреля 2019

Проблема

Что говорит заголовок, в основном.Учитывая строку, мне нужно извлечь из нее все, что является , а не начальным числом, за которым следует пробел.Итак, учитывая эту строку

"420 species of grass"

Я хотел бы получить

"species of grass"

Но, учитывая строку с номером не в начале, например

"The clock says it is 420"

или строка с номером без пробела, например

"It is 420 already"

Я хотел бы получить ту же строку с сохраненным номером

"The clock says it is 420"
"It is 420 already"

Что япробовал

Соответствие начального числа, за которым следует пробел, работает, как и ожидалось:

library(stringr)
str_extract_all("420 species of grass", "^\\d+(?=\\s)")
[[1]]
[1] "420"
> str_extract_all("The clock says it is 420", "^\\d+(?=\\s)")
[[1]]
character(0)
> str_extract_all("It is 420 already", "^\\d+(?=\\s)")
[[1]]
character(0)

Но, когда я пытаюсь сопоставить с чем угодно, кроме за начальным числом следует пробел, но не:

> str_extract_all("420 species of grass", "[^(^\\d+(?=\\s))]+")
[[1]]
[1] "species" "of"      "grass"  
> str_extract_all("The clock says it is 420", "[^(^\\d+(?=\\s))]+")
[[1]]
[1] "The"   "clock" "says"  "it"    "is" 
> str_extract_all("It is 420 already", "[^(^\\d+(?=\\s))]+")
[[1]]
[1] "It"      "is"      "already"

Кажется, это регулярное выражение соответствует чему угодно, кроме цифр и пробелов.

Как исправитьэто?

Ответы [ 3 ]

2 голосов
/ 23 апреля 2019

Я думаю, что ответ @ Дугласа является более кратким, однако, я предполагаю, что ваш фактический случай будет более сложным, и вы можете проверить ?regexpr, который может определить начальную позицию вашего конкретного шаблона.

Метод с использованием цикла for приведен ниже:


list <- list("420 species of grass",
               "The clock says it is 420",
               "It is 420 already")

extract <- function(x) {
  y <- vector('list', length(x))
  for (i in seq_along(x)) {
    if (regexpr("420", x[[i]])[[1]] > 1) {
      y[[i]] <- x[[i]]
       }
    else{
      y[[i]] <- substr(x[[i]], (regexpr(" ", x[[i]])[[1]] + 1), nchar(x[[i]]))

    }
  }
  return(y)
}

> extract(list)
[[1]]
[1] "species of grass"

[[2]]
[1] "The clock says it is 420"

[[3]]
[1] "It is 420 already"
1 голос
/ 23 апреля 2019

Я думаю, что самый простой способ сделать это, удалив числа вместо того, чтобы извлечь нужный шаблон:

library(stringr)

strings <- c("420 species of grass", "The clock says it is 420", "It is 420 already")
str_remove(strings, pattern = "^\\d+\\s")

[1] "species of grass"         "The clock says it is 420" "It is 420 already"
1 голос
/ 23 апреля 2019

Самый простой выход - заменить любые цифры, за которыми следуют пробелы, которые начинаются с начала строки, используя это регулярное выражение,

^\d+\s+

пустой строкой.

Regex Demo с использованием подстановки

Пример кода R с использованием под демо

sub("^\\d+\\s+", "", "420 species of grass")
sub("^\\d+\\s+", "", "The clock says it is 420")
sub("^\\d+\\s+", "", "It is 420 already")

Prints,

[1] "species of grass"
[1] "The clock says it is 420"
[1] "It is 420 already"

Альтернативный способ добиться того же, используя сопоставление, вы можете использовать следующее регулярное выражение и захватить содержимое группы1,

^(?:\d+\s+)?(.*)$

Демонстрация регулярного выражения с использованием соответствия

Кроме того, все, что вы помещаете в набор символов, теряет свое особое значение, например позитивный взгляд внутри него [^(^\\d+(?=\\s))]+, и просто ведет себя как литерал, поэтому ваше регулярное выражение становится неправильным.

Редактировать:

Хотя решение с использованием sub лучше, но если вам нужно решение на основе совпадений с использованием R-кодов, вам нужно использовать str_match вместо str_extract_all, а для доступа к содержимому группы 1 вам необходимо использовать [,2]

R Код Демо с использованием матча

library(stringr)

print(str_match("420 species of grass", "^(?:\\d+\\s+)?(.*)$")[,2])
print(str_match("The clock says it is 420", "^(?:\\d+\\s+)?(.*)$")[,2])
print(str_match("It is 420 already", "^(?:\\d+\\s+)?(.*)$")[,2])

Отпечатки,

[1] "species of grass"
[1] "The clock says it is 420"
[1] "It is 420 already"
...