使用JavaScript进行准确字数统计的正则表达式

19

我正在尝试编写一个正则表达式,用于在 JavaScript 命令中准确地计算文本区域中单词的数量。

我找到的其中一种解决方案如下:

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\b\w+\b/).length -1;

但这不包括任何非拉丁字符(例如:西里尔文,韩文字等);它完全跳过它们。

我还整理了另一个:

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\s+/g).length -1;
但是,这只有在文档以空格字符结尾时才能准确计数。如果在被计数的值后附加了一个空格字符,则即使文档为空,也会计算1个单词。此外,如果文档以空格字符开头,则会计算一个多余的单词。 是否有一个正则表达式可以将单词精确计数,而不受输入方法的影响?

3
离题了,但是 document.querySelector("#wordcount") 可以写成 document.getElementById("wordcount"),这样可能更适用于跨浏览器或更快;不太可能不兼容或更慢。 - T.J. Crowder
3
术语“word”的准确定义尚未给出。 - Tomalak
4
@Tomalak,是普遍缺失还是问题缺失?;) - David Tang
8个回答

43

这应该可以实现你想要的功能:

value.match(/\S+/g).length;

与其将字符串进行拆分,不如匹配任何非空白字符序列。

这样做还有额外的好处,如果需要的话可以轻松提取每个单词;)


谢谢。不过我有一个问题。使用match而不是split,当没有单词时会返回null,即使有空格字符。我可以使用if/else命令来解决这个问题,但是否有更好的方法? - 木川 炎星
8
我想知道发帖人对“you-and-I”被视为一个单词,或者“you & I”被视为三个单词,或者“you - and I”被视为四个单词的看法。 - Phrogz
@Haidon 如果你将 .match() 方法的返回值存储在变量 words 中,则 length = words && words.length || 0。 - David Tang
大家好,有人知道匹配“32 43.43 ...”(60个由空格分隔的数字)的正则表达式吗?谢谢。 - Nilesh
1
+1 谢谢,它有效,但我请求您将您的代码更改为 value.match(/\b\S+\b/g).length,因为它不会计算标点符号。例如,使用 /\S+/g 会将空格后的“?”计算为单词,这是您不想要的。 - King Friday

7

尝试计算任何非空格且具有单词边界的内容:

value.split(/\b\S+\b/g).length

您也可以尝试使用Unicode范围,但我不确定以下范围是否完整:

value.split(/[\u0080-\uFFFF\w]+/g).length

4
value.split不是正确的方法,但如果你改用(value.match(/\b\S+\b/g) || []).length,这个方法将会非常有效。我发现Phrogz在被接受的答案中的例子对于测试很有帮助;这样可以得出:count("you-and-I")==1count("you & I")==2count("you - and I")==3count("Phrogz's examples")==2。唯一有问题的是you-and-I,但这种构造方式很少见,因此可能不值得增加额外的复杂性,特别是为了确保获取所有所有格形式而进行修改。 - Kevin S

4

对我而言,这是最佳的结果:

value.split(/\b\W+\b/).length

使用

var words = value.split(/\b\W+\b/)

您得到所有的单词。

解释:

  • \b 表示单词边界
  • \W 表示非单词字符,通常大写表示否定
  • '+' 表示1个或多个字符或前缀的字符类

我建议学习正则表达式。它是一个非常强大的技能。 ;-)


3

尝试

    value.match(/\w+/g).length;

这将匹配一个可以在单词中出现的字符序列。而像这样的内容:
    value.match(/\S+/g).length;

如果用户添加逗号或其他标点符号,但后面没有空格,或者在逗号两侧添加了一个空格,则将导致计数不正确。


1
正确的正则表达式应该是/s+/,以便丢弃非单词:
'Lorem ipsum dolor , sit amet'.split(/\S+/g).length
7
'Lorem ipsum dolor , sit amet'.split(/\s+/g).length
6

2
你真的认为逗号应该被算作一个单词吗? - Phrogz
根据您的解决方案,' , , , , '共有5个单词:D - Emadpres
不准确,抱歉 - Mostafa Said

1

你可以像这样扩展/更改你的方法:

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.split(/\b\(.*?)\b/).length -1; 如果你想匹配电子邮件地址等内容

还有

document.querySelector("#wordcount").innerHTML = document.querySelector("#editor").value.trim().split(/\s+/g).length -1;

同时尝试使用\s,因为它是Unicode的\w

source:http://www.regular-expressions.info/charclass.html


0
我的简单的JavaScript库,叫做FuncJS,有一个名为"count()"的函数,它正如其名字所述——统计单词数量。
例如,假设你有一个由单词组成的字符串,你可以将它简单地放置在函数括号中,像这样:
count("How many words are in this string?");

然后调用该函数,它将返回单词数量。此外,该功能旨在忽略任何数量的空格,从而提供准确的结果。

要了解有关此函数的更多信息,请阅读http://docs.funcjs.webege.com/count().html上的文档,并且FuncJS的下载链接也在页面上。

希望这对想要做这个的任何人有所帮助! :)


0
const wordsCount = str.match(/\p{L}+/gu).length

这可能比已有的某些答案更好,但解释一下\p{L}是什么以及为什么它更好地解决了问题会非常有帮助。 - joanis
\p{L} 匹配来自任何语言的任何字母。 - chankruze
\p - 特殊点。当我们添加 /u 标志(表示 Unicode)时,它起作用。 {L} - 类别,L - 表示字母 因此,\p{L} 表示来自任何 Unicode 字母表的任何字母。它不包括数字和特殊字符。 - Вадим Булах

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接