Посчитать количество всех слов в строке
есть ли функция для подсчета количества слов в строке? Например:
str1 <- "How many words are in this sentence"
чтобы вернуть результат 7.
14 ответов:
используйте символ регулярного выражения
\W
для сопоставления символов без слов, используя+
чтобы указать один или несколько в строке, наряду сgregexpr
найти все совпадения в строке. Слова-это число разделителей слов плюс 1.lengths(gregexpr("\W+", str1)) + 1
это не удастся с пустыми строками в начале или конце символьного вектора, когда "слово" не удовлетворяет
\W
понятие не-слова (можно работать с другими регулярными выражениями,\S+
,[[:alpha:]]
и т. д. но там будет всегда будьте крайними случаями с подходом регулярных выражений) и т. д. Это, вероятно, более эффективно, чемstrsplit
решения, которые будут выделять память для каждого слова. Регулярные выражения описаны в?regex
.обновление как отмечено в комментариях и в другом ответе @Andri подход терпит неудачу с (нулевыми) и однословными строками, а также с конечной пунктуацией
> str1 = c("", "x", "x y", "x y!" , "x y! z") > lengths(gregexpr("[A-z]\W+", str1)) + 1L [1] 2 2 2 3 3
многие другие ответы также терпеть неудачу в этих или подобных (например, несколько пробелов) случаях. Я думаю, что предостережение моего ответа о "понятии одного слова" в исходном ответе охватывает проблемы с пунктуацией (решение: выберите другое регулярное выражение, например,
[[:space:]]+
), но нулевые и однословные случаи-это проблема; решение @Andri не может отличить ноль от одного слова. Таким образом, принимая "позитивный" подход к поиску слов можноsapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
, ведущей к
> sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0)) [1] 0 1 2 2 3
опять же регулярное выражение может быть уточнено для различных понятий "слово".
мне нравится использовать
gregexpr()
потому что это эффективная память. Альтернатива с помощьюstrsplit()
(как @user813966, но с регулярным выражением для разграничения слов) и использование исходного понятия разграничения слов является> lengths(strsplit(str1, "\W+")) [1] 0 1 2 2 3
это должно выделить новую память для каждого слова, которое создается, и для промежуточного списка слов. Это может быть относительно дорого, когда данные "большие", но, вероятно, это эффективно и понятно для большинства цели.
самый простой способ будет:
require(stringr) str_count("one, two three 4,,,, 5 6", "\S+")
... подсчет всех последовательностей на непересекающихся символах (
\S+
).но как насчет небольшой функции, которая позволяет нам также решить какой слова мы хотели бы рассчитывать и которой работает на целых векторах так же?
require(stringr) nwords <- function(string, pseudo=F){ ifelse( pseudo, pattern <- "\S+", pattern <- "[[:alpha:]]+" ) str_count(string, pattern) } nwords("one, two three 4,,,, 5 6") # 3 nwords("one, two three 4,,,, 5 6", pseudo=T) # 6
str2 <- gsub(' {2,}',' ',str1) length(strsplit(str2,' ')[[1]])
The
gsub(' {2,}',' ',str1)
убедитесь, что все слова разделены только одним пробелом, заменив все вхождения двух или более пробелов одним пробелом.The
strsplit(str,' ')
разбивает предложение на все пробелы и возвращает результат в виде списка. Элемент[[1]]
захватывает вектор слов из этого списка. Элементlength
подсчитывает, сколько слов.> str1 <- "How many words are in this sentence" > str2 <- gsub(' {2,}',' ',str1) > str2 [1] "How many words are in this sentence" > strsplit(str2,' ') [[1]] [1] "How" "many" "words" "are" "in" "this" "sentence" > strsplit(str2,' ')[[1]] [1] "How" "many" "words" "are" "in" "this" "sentence" > length(strsplit(str2,' ')[[1]]) [1] 7
Я использую С
stringr
библиотека с escape последовательность\w
представляет:любой символ "слово" (буква, цифра или подчеркивание в текущем locale: в режиме UTF-8 учитываются только буквы и цифры ASCII)
пример:
> str_count("How many words are in this sentence", '\w+') [1] 7
из всех остальных 9 ответов, которые я смог проверить, только два (Винсент Зоонекинд и петермейсснер) работали для всех представленных здесь входов, поэтому далеко, но они тоже требуют
stringr
.но только это решение работает со всеми входами, представленными до сих пор, плюс входы, такие как
"foo+bar+baz~spam+eggs"
или"Combien de mots sont dans cette phrase ?"
.Benchmark:
library(stringr) questions <- c( "", "x", "x y", "x y!", "x y! z", "foo+bar+baz~spam+eggs", "one, two three 4,,,, 5 6", "How many words are in this sentence", "How many words are in this sentence", "Combien de mots sont dans cette phrase ?", " Day after day, day after day, We stuck, nor breath nor motion; " ) answers <- c(0, 1, 2, 2, 3, 5, 6, 7, 7, 7, 12) score <- function(f) sum(unlist(lapply(questions, f)) == answers) funs <- c( function(s) sapply(gregexpr("\W+", s), length) + 1, function(s) sapply(gregexpr("[[:alpha:]]+", s), function(x) sum(x > 0)), function(s) vapply(strsplit(s, "\W+"), length, integer(1)), function(s) length(strsplit(gsub(' {2,}', ' ', s), ' ')[[1]]), function(s) length(str_match_all(s, "\S+")[[1]]), function(s) str_count(s, "\S+"), function(s) sapply(gregexpr("\W+", s), function(x) sum(x > 0)) + 1, function(s) length(unlist(strsplit(s," "))), function(s) sapply(strsplit(s, " "), length), function(s) str_count(s, '\w+') ) unlist(lapply(funs, score))
выход:
6 10 10 8 9 9 7 6 6 11
можно использовать
str_match_all
, с регулярным выражением, которое будет идентифицировать ваши слова. Следующие работы с начальными, конечными и дублированными пространствами.library(stringr) s <- " Day after day, day after day, We stuck, nor breath nor motion; " m <- str_match_all( s, "\S+" ) # Sequences of non-spaces length(m[[1]])
попробуйте эту функцию из
stringi
пакетаrequire(stringi) > s <- c("Lorem ipsum dolor sit amet, consectetur adipisicing elit.", + "nibh augue, suscipit a, scelerisque sed, lacinia in, mi.", + "Cras vel lorem. Etiam pellentesque aliquet tellus.", + "") > stri_stats_latex(s) CharsWord CharsCmdEnvir CharsWhite Words Cmds Envirs 133 0 30 24 0 0
можно использовать wc в библиотеке qdap:
> str1 <- "How many words are in this sentence" > wc(str1) [1] 7
вы можете удалить двойные пробелы и подсчитать количество
" "
в строке, чтобы получить количество слов. использовать stringr иrm_white
{qdapRegex}str_count(rm_white(s), " ") +1
решение 7 не дает правильного результата в случае, если есть только одно слово. Вы должны не просто подсчитывать элементы в результате gregexpr (который равен -1, если там, где не соответствует), но подсчитывать элементы > 0.
Ergo:
sapply(gregexpr("\W+", str1), function(x) sum(x>0) ) + 1