Я пытаюсь определить, является ли строка подмножеством другой строки. Например:
chars <- "test"
value <- "es"
Я хочу вернуть TRUE, если «value» появляется как часть строки «chars». В следующем сценарии я хотел бы вернуть false:
chars <- "test"
value <- "et"
fixed=TRUE
, иначе вы воспринимаете его как регулярное выражение вместо строки. Смотрите мой ответ с октября 2016 года.fixed=TRUE
либо у вас есть ошибка, которая тихо и незаметно испортит ваши данные.Ответы:
Используйте
grepl
функциюИспользуйте,
?grepl
чтобы узнать больше.источник
vec <- replicate(100000, paste( sample(letters, 10, replace=TRUE), collapse='') )
.system.time(a <- grepl("abc", vec))
иsystem.time(a <- grepl("abc", vec, fixed=TRUE))
, иfixed=TRUE
до сих пор, если что - нибудь немного медленнее. Разница невелика с этими короткими строками, ноfixed=TRUE
, похоже, не быстрее. Спасибо, что указали, однако, что это на длинных струнах, которыеfixed=TRUE
принимают настоящий удар.Ответ
Вздох, мне понадобилось 45 минут, чтобы найти ответ на этот простой вопрос. Ответ:
grepl(needle, haystack, fixed=TRUE)
интерпретация
grep
назван в честь исполняемого файла linux, который сам по себе является аббревиатурой « G lobal R egular E xpression P rint», он будет читать строки ввода и затем печатать их, если они соответствуют аргументам, которые вы дали. «Глобальный» означал, что совпадение может произойти в любом месте строки ввода, я объясню «Регулярное выражение» ниже, но идея в том, что это более разумный способ сопоставления строки (например, R вызывает этот «символ»class("abc")
) и «Печать». msgstr "потому что это программа командной строки, испускание вывода означает, что он печатает в свою строку выводаТеперь
grep
программа представляет собой фильтр, от строк ввода до строк вывода. И похоже, чтоgrep
функция R аналогично будет принимать массив входов. По причинам, которые мне совершенно неизвестны (я начал играть с R около часа назад), он возвращает вектор совпадающих индексов, а не список совпадений.Но, возвращаясь к вашему первоначальному вопросу, мы действительно хотим узнать, нашли ли мы иголку в стоге сена, истинное / ложное значение. Они , видимо , решили назвать эту функцию
grepl
, как и в «Grep» , но с « L ogical» возвращаемого значения (они называют истинные и ложные логические значения, напримерclass(TRUE)
).Итак, теперь мы знаем, откуда пришло название и что оно должно делать. Вернемся к регулярным выражениям. Аргументы, даже если они являются строками, они используются для построения регулярных выражений (далее: regex). Регулярное выражение - это способ сопоставления строки (если это определение вас раздражает, отпустите его). Например, регулярное выражение
a
соответствует символу"a"
, регулярное выражениеa*
соответствует символу"a"
0 или более раз, а регулярное выражениеa+
соответствует символу"a"
1 или более раз. Следовательно, в приведенном выше примере стрелка, которую мы ищем1+2
, когда рассматривается как регулярное выражение, означает «один или более 1, а затем 2» ... но за нашей следует плюс!Таким образом, если вы используете
grepl
без установкиfixed
, ваши иглы будут случайно стогами сена, и это будет работать случайно довольно часто, мы можем видеть, что это работает даже на примере ОП. Но это скрытая ошибка! Нам нужно сказать, что входные данные - это строка, а не регулярное выражение, что, по-видимому,fixed
и для этого. Почему исправлено? Понятия не имею, добавьте этот ответ в закладки, потому что вам, вероятно, придется искать его еще 5 раз, прежде чем вы его запомните.Несколько заключительных мыслей
Чем лучше ваш код, тем меньше истории вы должны знать, чтобы понять его. Каждый аргумент может иметь по крайней мере два интересных значения (в противном случае он не должен быть аргументом), в документе приведен список из 9 аргументов, что означает, что есть как минимум 2 ^ 9 = 512 способов вызвать его, это много работы для писать, тестировать и запоминать ... разъединять такие функции (разбивать их, удалять зависимости друг от друга, строковые объекты отличаются от регулярных выражений, а не от векторных). Некоторые из этих опций также являются взаимоисключающими, не дают пользователям неправильных способов использования кода, то есть проблемный вызов должен быть структурно бессмысленным (например, передавать несуществующую опцию), а не логически бессмысленным (где вы должны выдать предупреждение, чтобы объяснить это). Положите в переносном смысле: заменить входную дверь на 10-м этаже стеной лучше, чем вывесить табличку, предупреждающую о ее использовании, но лучше либо нет, либо нет. В интерфейсе функция определяет, как должны выглядеть аргументы, а не вызывающая сторона (поскольку вызывающая сторона зависит от функции, вывод всего того, с чем каждый может захотеть вызвать ее, делает функцию зависимой и от вызывающих, и от этого типа циклическая зависимость быстро забьет систему и никогда не даст ожидаемых результатов). Будьте очень осторожны с двусмысленными типами, это недостаток дизайна, который Вывод всего, что каждый может захотеть вызвать, делает функцию зависимой и от вызывающих, и этот тип циклической зависимости быстро забьет систему и никогда не даст ожидаемых результатов). Будьте очень осторожны с двусмысленными типами, это недостаток дизайна, который Вывод всего, что каждый может захотеть вызвать, делает функцию зависимой и от вызывающих, и этот тип циклической зависимости быстро забьет систему и никогда не даст ожидаемых результатов). Будьте очень осторожны с двусмысленными типами, это недостаток дизайна, который
TRUE
и0
и"abc"
все векторы.источник
grep
фильтровать строки, а не ячейки.Вы хотите
grepl
:источник
Используйте эту функцию из
stringi
пакета:Некоторые тесты:
источник
Также это можно сделать с помощью библиотеки "stringr":
источник
На всякий случай, если вы также хотите проверить, содержит ли строка (или набор строк) несколько подстрок, вы также можете использовать '|' между двумя подстроками.
Ты получишь
так как 1-е слово имеет подстроку «как», а последнее слово содержит подстроку «в»
источник
Используйте
grep
илиgrepl
но знайте, хотите ли вы использовать регулярные выражения .По умолчанию
grep
и related принимают регулярное выражение для сопоставления, а не литеральную подстроку. Если вы этого не ожидаете и пытаетесь найти недопустимое регулярное выражение, это не сработает:Чтобы сделать настоящий тест подстроки, используйте
fixed = TRUE
.Если вы хотите регулярное выражение, отлично, но это не то, о чем спрашивает OP.
источник
Ты можешь использовать
grep
источник
Аналогичная проблема здесь: учитывая строку и список ключевых слов, определите, какие из ключевых слов, если таковые имеются, содержатся в строке.
Рекомендации этой темы предлагают
stringr
«sstr_detect
иgrepl
. Вот тесты изmicrobenchmark
пакета:С помощью
а потом
мы нашли
Как вы можете видеть, более 5000 итераций поиск по ключевым словам с помощью
str_detect
иgrepl
по практической строки и вектора ключевых слов,grepl
выполняет совсем немного лучшеstr_detect
.Результатом является логический вектор,
r
который определяет, какие из ключевых слов, если таковые имеются, содержатся в строке.Поэтому я рекомендую использовать,
grepl
чтобы определить, есть ли какие-либо ключевые слова в строке.источник