Извлечь совпадающие слова из строк по порядку

Если у меня есть две строки, которые выглядят так:

x <- "Here is a test of words and stuff."
y <- "Here is a better test of words and stuff."

Есть ли простой способ проверить слова слева направо и создать новую строку совпадающих слов, а затем остановиться, когда слова больше не совпадают, поэтому вывод будет выглядеть так:

> "Here is a"

Я не хочу находить все совпадающие слова между двумя строками, а только слова, которые совпадают по порядку. Так что "слова и прочее". находится в обеих строках, но я не хочу, чтобы это было выбрано.

Итак, если две строки начинаются с другого слова, ничего не должно возвращаться? Вы сопоставляете только заполняющие слова? А как насчет x<-"abcd" и y<-"abyz". Там тоже ничего не вернут?

MrFlick 13.02.2023 21:14

Правильно, я хотел бы извлечь только те слова, которые совпадают, начиная с начала строк. "abcd" и "abyz" не совпадают, так как это разные слова. Было бы совпадение, если бы это были "ab cd" и "ab yz", и возвращалось бы только "ab".

Overtime4728 13.02.2023 21:17
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
Уроки CSS 6
Уроки CSS 6
Здравствуйте дорогие читатели, я Ферди Сефа Дюзгюн, сегодня мы продолжим с вами уроки css. Сегодня мы снова продолжим с так называемых классов.
Что такое Css? Для чего он используется?
Что такое Css? Для чего он используется?
CSS, или "Каскадные таблицы стилей", - это язык стилей, используемый в веб-страницах. CSS является одним из основных инструментов веб-разработки...
2
2
62
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Это показывает вам первые n слова, которые соответствуют:

xvec <- strsplit(x, " +")[[1]]
yvec <- strsplit(y, " +")[[1]]
(len <- min(c(length(xvec), length(yvec))))
# [1] 8
i <- which.max(cumsum(head(xvec, len) != head(yvec, len)))
list(xvec[1:i], yvec[1:i])
# [[1]]
# [1] "Here"   "is"     "a"      "test"   "of"     "words"  "and"    "stuff."
# [[2]]
# [1] "Here"   "is"     "a"      "better" "test"   "of"     "words"  "and"   
cumsum(head(xvec, len) != head(yvec, len))
# [1] 0 0 0 1 2 3 4 5
i <- which.max(cumsum(head(xvec, len) != head(yvec, len)) > 0)
list(xvec[1:(i-1)], yvec[1:(i-1)])
# [[1]]
# [1] "Here" "is"   "a"   
# [[2]]
# [1] "Here" "is"   "a"   

Отсюда мы можем легко получить ведущую строку:

paste(xvec[1:(i-1)], collapse = " ")
# [1] "Here is a"

А остальные строки с

paste(xvec[-(1:(i-1))], collapse = " ")
# [1] "test of words and stuff."

Я написал функцию, которая проверит строку и вернет желаемый результат:

x <- "Here is a test of words and stuff."
y <- "Here is a better test of words and stuff."
z <- "This string doesn't match"

library(purrr)

check_str <- function(inp, pat, delimiter = "\\s") {

  inp <- unlist(strsplit(inp, delimiter))
  pat <- unlist(strsplit(pat, delimiter))
  ln_diff <- length(inp) - length(pat)
  
  if (ln_diff < 0) {
    inp <- append(inp, rep("", abs(ln_diff)))
  }
  if (ln_diff > 0) {
    pat <- append(pat, rep("", abs(ln_diff)))
  }
  
  idx <- map2_lgl(inp, pat, ~ identical(.x, .y))
  rle_idx <- rle(idx)
  
  if (rle_idx$values[1]) {
    idx2 <- seq_len(rle_idx$length[1])
  } else {
    idx2 <- 0
  }
  
  paste0(inp[idx2], collapse = delimiter)
}

check_str(x, y, " ")
#> [1] "Here is a"
check_str(x, z, " ")
#> [1] ""

Created on 2023-02-13 with reprex v2.0.2

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

common_start<-function(x, y) {
  i <- 1
  last <- NA
  while (i <= nchar(x) & i <= nchar(x)) {
    if (substr(x,i,i) == substr(y,i,i)) {
      if (grepl("[[:space:][:punct:]]", substr(x,i,i), perl=T)) {
        last <- i
      }
    } else {
      break;
    }
    i <- i + 1
  }
  if (!is.na(last)) {
    substr(x, 1, last-1)
  } else {
    NA
  }
}

И используйте это с вашими образцами

common_start(x,y)
# [1] "Here is a"

Идея состоит в том, чтобы проверять каждый символ, отслеживая последний символ, не являющийся словом, который все еще соответствует. Использование цикла while может быть непривлекательным, но это означает, что вы можете прервать работу раньше, не обрабатывая всю строку, как только будет обнаружено несоответствие.

Ответ принят как подходящий

Разделите строки, вычислите минимальную длину двух разделений, возьмите это количество слов из заголовка каждого и добавьте FALSE, чтобы гарантировать, что несоответствие может произойти при сопоставлении соответствующих слов. Затем используйте which.min, чтобы найти первое несоответствие, возьмите это число минус 1 слов и снова соедините их.

L <- strsplit(c(x, y), " +")
wx <- which.min(c(do.call(`==`, lapply(L, head, min(lengths(L)))), FALSE))
paste(head(L[[1]], wx - 1), collapse = " ")
## [1] "Here is a"

Другие вопросы по теме