计算字符串中所有单词的数量

Joh*_*ohn 71 string r word-count

是否有一个函数来计算字符串中的单词数?例如:

str1 <- "How many words are in this sentence"
Run Code Online (Sandbox Code Playgroud)

返回7的结果.

Mar*_*gan 67

使用正则表达式符号\\W匹配非单词字符,+用于指示一行中的一个或多个,以及gregexpr查找字符串中的所有匹配项.单词是单词分隔符的数量加1.

lengths(gregexpr("\\W+", str1)) + 1
Run Code Online (Sandbox Code Playgroud)

这将失败,并在开始或特征向量的结束,空字符串时,一个"字"不满足\\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
Run Code Online (Sandbox Code Playgroud)

许多其他答案也在这些或类似(例如,多个空格)的情况下失败.我想我的答案是关于"一个词的概念"在原来的答案告诫涵盖标点符号的问题(解决办法:选择不同的正则表达式,如[[:space:]]+),但零一个字的情况下是一个问题; @Andri的解决方案无法区分零和一个单词.因此,采取"积极"的方法来寻找一个可能的话

sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
Run Code Online (Sandbox Code Playgroud)

导致

sapply(gregexpr("[[:alpha:]]+", str1), function(x) sum(x > 0))
# [1] 0 1 2 2 3
Run Code Online (Sandbox Code Playgroud)

同样,正则表达式可能会针对"单词"的不同概念进行细化.

我喜欢使用gregexpr()因为它的内存效率.使用的替代方法strsplit()(如@ user813966,但使用正则表达式来分隔单词)并利用分隔单词的原始概念是

lengths(strsplit(str1, "\\W+"))
# [1] 0 1 2 2 3
Run Code Online (Sandbox Code Playgroud)

这需要为每个创建的单词和中间单词列表分配新的内存.当数据"很大"时,这可能相对昂贵,但对于大多数目的而言,这可能是有效且可理解的.


pet*_*ner 43

最简单的方法是:

require(stringr)
str_count("one,   two three 4,,,, 5 6", "\\S+")
Run Code Online (Sandbox Code Playgroud)

...计算非空格字符上的所有序列(\\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
Run Code Online (Sandbox Code Playgroud)


are*_*lek 26

我使用库中的str_count函数stringr和转义序列\w来表示:

任何'word'字符(当前语言环境中的字母,数字或下划线:在UTF-8模式下,只考虑ASCII字母和数字)

例:

> str_count("How many words are in this sentence", '\\w+')
[1] 7
Run Code Online (Sandbox Code Playgroud)

在我能够测试的所有其他9个答案中,只有两个(由Vincent Zoonekynd和petermeissner)为目前为止提供的所有输入工作,但他们也需要stringr.

但只有这个解决方案适用于目前为止提供的所有输入,以及诸如"foo+bar+baz~spam+eggs"或之类的输入"Combien de mots sont dans cette phrase ?".

基准测试:

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))
Run Code Online (Sandbox Code Playgroud)

输出:

6 10 10  8  9  9  7  6  6 11
Run Code Online (Sandbox Code Playgroud)

  • @Thredolsen 如果您确定没有撇号应该被视为单词分隔符,您可以使用字符类 `'[\\w\']+'`(无法测试,所以 https:// xkcd.com/1638/ 可能适用),否则我不确定正则表达式是否足够强大以在一般情况下处理它:) (3认同)
  • 在此注释中,我将使用纯正则表达式语法,因此示例将需要一些额外的反斜杠。为了覆盖诸如“ o'clock”和“ friggin”之类的单词,您可以执行“ \ w +('\ w *)?”(我不知道是否有以撇号开头的单词?)。要另外处理小时数,您可以尝试将它们匹配,例如[`\ d?\ d:\ d \ d | \ w +('\ w *)?`](http://regexr.com/4b2rk)甚至可以做一些事情根据您的需要更复杂。但这与R的关系越来越少,而与如何定义单词的关系也越来越多,因此也许您可以发布一个单独的问题来满足您的特定需求? (2认同)

AVS*_*esh 17

你可以使用strsplitsapply功能

sapply(strsplit(str1, " "), length)
Run Code Online (Sandbox Code Playgroud)

  • 双重空间怎么样? (4认同)
  • 只是一个更新,你现在可以在基 R 中使用有点新的 `lengths` 函数,它可以找到每个元素的长度:`lengths(strsplot(str, " "))` (2认同)

mat*_*fee 15

str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])
Run Code Online (Sandbox Code Playgroud)

gsub(' {2,}',' ',str1)品牌确保所有单词都只有一个空格分开,用一个空格替换两个或多个空格的所有出现.

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
Run Code Online (Sandbox Code Playgroud)


Vin*_*ynd 13

您可以使用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]])
Run Code Online (Sandbox Code Playgroud)


bar*_*nus 11

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 
Run Code Online (Sandbox Code Playgroud)

  • @bartektartanusthat是一些不错的功能! (6认同)
  • 谢谢:)从这个包中检查其余的功能!我相信你会发现一些有趣的东西:)欢迎任何评论! (5认同)

yuq*_*ian 7

你可以在库qdap中使用wc函数:

> str1 <- "How many words are in this sentence"
> wc(str1)
[1] 7
Run Code Online (Sandbox Code Playgroud)


CJu*_*unk 7

require(stringr)
str_count(x,"\\w+")
Run Code Online (Sandbox Code Playgroud)

单词之间有双/三空格就可以了

所有其他答案都存在单词之间存在多个空格的问题。


小智 6

您可以删除双空格并计算" "字符串中的数字以获取单词的数量.使用stringrrm_white{ qdapRegex }

str_count(rm_white(s), " ") +1
Run Code Online (Sandbox Code Playgroud)


小智 5

在只有一个单词的情况下,解决方案 7 不会给出正确的结果。您不应该只计算 gregexpr 结果中的元素(如果其中不匹配,则为 -1),而应该计算 > 0 的元素。

因此:

sapply(gregexpr("\\W+", str1), function(x) sum(x>0) ) + 1 
Run Code Online (Sandbox Code Playgroud)


San*_*ram 5

试试这个

length(unlist(strsplit(str1," ")))
Run Code Online (Sandbox Code Playgroud)


Sot*_*tos 5

同样来自stringi包,直接功能stri_count_words

stringi::stri_count_words(str1)
#[1] 7
Run Code Online (Sandbox Code Playgroud)