我需要采取一系列混合的亚洲人物(现在只假设中国汉字或日本汉字/平假名/片假名)和“字母数字”(即Enlgish,法语),并按以下方式计算: / p>
1)将每个亚洲字符数计为1; 2)将每个字母数字WORD计为1;
一些例子:
株式会社myCompany = 4个字符+ 1个字=总共5个 株式会社マイコ= 7个字符
到目前为止我唯一的想法是使用:
var wordArray=val.split(/\w+/);
然后检查每个元素以查看其内容是否为字母数字(因此计为1)或不是(因此取数组长度)。但我觉得这根本不是很聪明,被计算的文字可能高达10,000字,所以不是很快。
想法?
答案 0 :(得分:3)
不幸的是,JavaScript的RegExp
不支持Unicode字符类; \w
仅适用于ASCII字符(以某些浏览器错误为模)。
但是,您可以在组中使用Unicode字符,因此如果您可以将您感兴趣的每组字符隔离为范围,则可以执行此操作。例如:
var r= new RegExp(
'[A-Za-z0-9_\]+|'+ // ASCII letters (no accents)
'[\u3040-\u309F]+|'+ // Hiragana
'[\u30A0-\u30FF]+|'+ // Katakana
'[\u4E00-\u9FFF\uF900-\uFAFF\u3400-\u4DBF]', // Single CJK ideographs
'g');
var nwords= str.match(r).length;
(这试图为日语提供更真实的'单词'计数,将每种假名的每一次计算都算作一个单词。当然,这仍然是不对的,但它可能比将每个音节视为一个单词更接近。)
显然,如果你想“正确地做”,还需要考虑更多的角色。我们希望你没有基本的多语言平面以外的角色,只有一个!
答案 1 :(得分:-1)
您可以迭代文本中的每个字符,检查每个字符以查找分词符。以下示例执行此操作,将每个中文/日文/韩文(CJK)表意文字计为单个单词,并将所有字母数字字符串视为单个单词。
关于我的实施的一些注意事项:
它可能无法正确处理重音字符。他们可能会触发单词突破。您可以修改wordBreakRegEx
来解决此问题。
cjkRegEx
不包含一些更深奥的代码点范围,因为它们需要5个十六进制数字来引用,而JavaScript的正则表达式引擎似乎不允许您这样做。但你可能不需要担心这些,因为我甚至认为大多数字体都不包括它们。
我故意将日语平假名和片假名从cjkRegEx
中删除,因为我不确定你想怎么处理这些。根据您正在处理的文本类型,将它们的字符串视为单个单词可能更有意义。在这种情况下,您需要添加逻辑来识别“假名单词”而不是“字母数字单词”。如果您不在乎,则只需将其代码点范围添加到cjkRegEx
即可。当然,您可以尝试识别假名字符串中的单词分隔符,但很快就会变得很难。
示例实施:
function getWordCount(text) {
// This matches all CJK ideographs.
var cjkRegEx = /[\u3400-\u4db5\u4e00-\u9fa5\uf900-\ufa2d]/;
// This matches all characters that "break up" words.
var wordBreakRegEx = /\W/;
var wordCount = 0;
var inWord = false;
var length = text.length;
for (var i = 0; i < length; i++) {
var curChar = text.charAt(i);
if (cjkRegEx.test(curChar)) {
// Character is a CJK ideograph.
// Count it as a word.
wordCount += inWord ? 2 : 1;
inWord = false;
} else if (wordBreakRegEx.test(curChar)) {
// Character is a "word-breaking" character.
// If a word was started, increment the word count.
if (inWord) {
wordCount += 1;
inWord = false;
} else {
// All other characters are "word" characters.
// Indicate that a word has begun.
inWord = true;
}
}
// If the text ended while in a word, make sure to count it.
if (inWord) {
wordCount += 1;
}
return wordCount;
}
Unihan Database对于在unicode中学习CJK非常有帮助。当然,Unicode home page也有大量的信息。
答案 2 :(得分:-2)
我认为你想循环遍历所有字符,并且每当当前字符与前一个字符在一个不同的单词(根据你的定义)时增加一个计数器。