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

时间:2012-01-19 01:56:40

标签: r string word-count

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

str1 <- "How many words are in this sentence"

返回7的结果。

17 个答案:

答案 0 :(得分:65)

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

lengths(gregexpr("\\W+", str1)) + 1

如果“单词”不满足\\W的非单词概念(可以使用其他正则表达式,{},那么在字符向量的开头或结尾会出现空字符串失败{1}},\\S+等等,但总是存在使用正则表达式方法的边缘情况)等等。它可能比[[:alpha:]]解决方案更有效,它将为每个单词分配内存。正则表达式在strsplit中描述。

更新如评论和@Andri的不同答案中所述,该方法以(零)和单字符串以及尾随标点符号失败

?regex

许多其他答案也在这些或类似(例如,多个空格)的情况下失败。我认为我的回答是关于原始答案中“一个词的概念”的回答,包括标点符号的问题(解决方案:选择不同的正则表达式,例如str1 = c("", "x", "x y", "x y!" , "x y! z") lengths(gregexpr("[A-z]\\W+", str1)) + 1L # [1] 2 2 2 3 3 ),但零和一个单词的情况是个问题; @Andri的解决方案无法区分零和一个单词。因此采取“积极”的方法来寻找一个可能

的单词
[[:space:]]+

导致

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()的替代方法(如@ user813966,但使用正则表达式来分隔单词)并使用原始的分隔单词概念

strsplit()

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

答案 1 :(得分:39)

最简单的方法将是:

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

答案 2 :(得分:23)

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

  

任何'字'字符(当前字母,数字或下划线)   locale:在UTF-8模式下,只考虑ASCII字母和数字)

示例:

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

在我能够测试的所有其他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))

输出:

6 10 10  8  9  9  7  6  6 11

答案 3 :(得分:15)

str2 <- gsub(' {2,}',' ',str1)
length(strsplit(str2,' ')[[1]])

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

答案 4 :(得分: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]])

答案 5 :(得分:12)

您可以使用strsplitsapply功能

sapply(strsplit(str1, " "), length)

答案 6 :(得分: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 

答案 7 :(得分:7)

您可以在库 qdap 中使用 wc 功能:

> str1 <- "How many words are in this sentence"
> wc(str1)
[1] 7

答案 8 :(得分:6)

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

str_count(rm_white(s), " ") +1

答案 9 :(得分:5)

试试这个

length(unlist(strsplit(str1," ")))

答案 10 :(得分:4)

在只有一个单词的情况下,解决方案7没有给出正确的结果。 你不应该只计算gregexpr结果中的元素(如果不匹配则为-1),但计算元素&gt; 0

埃尔戈:

sapply(gregexpr("\\W+", str1), function(x) sum(x>0) ) + 1 

答案 11 :(得分:1)

也是public class SongListAdapter extends FragmentStatePagerAdapter { String tabTitles[] = new String[]{"Recommended", "Popular", "Rock", "Pop", "Blues", "Chill"}; Context context; private ArrayList<Audio> audioList; public SongListAdapter(FragmentManager fm, Context context) { super(fm); this.context = context; } @Override public int getCount() { return tabTitles.length; } @Override public SongListFragment getItem(int position) { SongListFragment slf = new SongListFragment(); slf.setAudioList(getAudioList()); slf.setItemOnClickListener(new SongListFragment.SongListItemOnClickListener() { @Override public void onClick(Audio audio) { System.out.println("asdfdas"); itemListener.onClick(audio); } }); return slf; } @Override public CharSequence getPageTitle(int position) { // Generate title based on item position return tabTitles[position]; } public View getTabView(int position) { View tab = LayoutInflater.from(context).inflate(R.layout.custom_tab, null); TextView tv = tab.findViewById(R.id.custom_text); tv.setText(tabTitles[position]); return tab; } public ArrayList<Audio> getAudioList() { return audioList; } public void setAudioList(ArrayList<Audio> audioList) { this.audioList = audioList; } SongListViewPagerListViewItemListener itemListener; public void setItemListener(SongListViewPagerListViewItemListener itemListener) { this.itemListener = itemListener; } public interface SongListViewPagerListViewItemListener { void onClick(Audio audio); } } 包中的简单函数stringi

stri_count_words

答案 12 :(得分:1)

require(stringr)

定义一个非常简单的功能

str_words <- function(sentence) {

  str_count(sentence, " ") + 1

}

检查

str_words(This is a sentence with six words)

答案 13 :(得分:0)

我发现以下功能和正则表达式可用于字数统计,特别是在处理单连字符和双连字符时,前者通常不应算作断字,例如,众所周知的高保真;而双连字符是不受空格限制的标点分隔符,例如用于括号的注释。

txt <- "Don't you think e-mail is one word--and not two!" #10 words
words <- function(txt) { 
length(attributes(gregexpr("(\\w|\\w\\-\\w|\\w\\'\\w)+",txt)[[1]])$match.length) 
}

words(txt) #10 words

Stringi是有用的软件包。但是由于连字符,本例中的单词过多。

stringi::stri_count_words(txt) #11 words

答案 14 :(得分:0)

使用 stringr 包,还可以编写一个简单的脚本,该脚本可以遍历字符串向量,例如通过for循环。

  

df $ text

包含一个我们感兴趣的字符串向量。首先,我们向现有数据框df中添加其他列,如下所示:

df$strings    = as.integer(NA)
df$characters = as.integer(NA)

然后我们对字符串向量进行如下循环:

for (i in 1:nrow(df)) 
{
   df$strings[i]    = str_count(df$text[i], '\\S+') # counts the strings
   df$characters[i] = str_count(df$text[i])         # counts the characters & spaces
}

结果列: strings character 将包含单词和字符的计数,并且可以一次性实现向量字符串。

答案 15 :(得分:0)

require(stringr)
str_count(x,"\\w+")

可以很好地使用单词之间的双/三空格

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

答案 16 :(得分:0)

使用nchar

如果调用字符串向量x

(nchar(x) - nchar(gsub(' ','',x))) + 1

找出空格数,然后添加一个