使用javascript,我如何计算亚洲字符和英语单词的混合

时间:2010-02-23 01:09:49

标签: javascript text character counting

我需要采取一系列混合的亚洲人物(现在只假设中国汉字或日本汉字/平假名/片假名)和“字母​​数字”(即Enlgish,法语),并按以下方式计算: / p>

1)将每个亚洲字符数计为1; 2)将每个字母数字WORD计为1;

一些例子:

株式会社myCompany = 4个字符+ 1个字=总共5个 株式会社マイコ= 7个字符


到目前为止我唯一的想法是使用:

var wordArray=val.split(/\w+/);

然后检查每个元素以查看其内容是否为字母数字(因此计为1)或不是(因此取数组长度)。但我觉得这根本不是很聪明,被计算的文字可能高达10,000字,所以不是很快。

想法?

3 个答案:

答案 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)表意文字计为单个单词,并将所有字母数字字符串视为单个单词。

关于我的实施的一些注意事项:

  1. 它可能无法正确处理重音字符。他们可能会触发单词突破。您可以修改wordBreakRegEx来解决此问题。

  2. cjkRegEx不包含一些更深奥的代码点范围,因为它们需要5个十六进制数字来引用,而JavaScript的正则表达式引擎似乎不允许您这样做。但你可能不需要担心这些,因为我甚至认为大多数字体都不包括它们。

  3. 我故意将日语平假名和片假名从cjkRegEx中删除,因为我不确定你想怎么处理这些。根据您正在处理的文本类型,将它们的字符串视为单个单词可能更有意义。在这种情况下,您需要添加逻辑来识别“假名单词”而不是“字母数字单词”。如果您不在乎,则只需将其代码点范围添加到cjkRegEx即可。当然,您可以尝试识别假名字符串中的单词分隔符,但很快就会变得很难。

  4. 示例实施:

    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)

我认为你想循环遍历所有字符,并且每当当前字符与前一个字符在一个不同的单词(根据你的定义)时增加一个计数器。