используя javascript, как я могу посчитать смесь азиатских символов и английских слов - PullRequest
6 голосов
/ 23 февраля 2010

Мне нужно взять строку из смешанных азиатских символов (на данный момент, допустим, только китайский кандзи или японский кандзи / хирагана / катакана) и "алфавитно-цифровые" (т. Е. Английский, французский) и считать их следующим образом: 1001 *

1) считать каждый азиатский символ 1; 2) считать каждое буквенно-цифровое слово 1;

несколько примеров:

株式会社 myCompany = 4 знака + 1 слово = всего 5 7 マ イ コ = 7 символов


Моя единственная идея пока состоит в том, чтобы использовать:

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

, а затем проверьте каждый элемент, чтобы увидеть, является ли его содержимое буквенно-цифровым (так считать 1) или нет (поэтому возьмите длину массива). Но я не думаю, что это действительно очень умно, и подсчитываемый текст может содержать до 10 000 слов, поэтому не очень быстро.

Идеи

Ответы [ 3 ]

3 голосов
/ 23 февраля 2010

К сожалению, RegExp в JavaScript не поддерживает символы Unicode; \w применяется только к символам ASCII (по модулю некоторых ошибок браузера).

Вы можете использовать символы Юникода в группах, однако, вы можете сделать это, если вы можете выделить каждый набор символов, который вас интересует, как диапазон. eg.:

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;

(Это попытка дать более реалистичный подсчет «слов» для японцев, считая каждый прогон одного типа каны как слова. Конечно, это все еще не правильно, но, вероятно, это ближе, чем рассматривать каждый слог как одно слово .)

Очевидно, что есть еще много персонажей, которые нужно учитывать, если вы хотите «сделать это правильно». Будем надеяться, что у вас нет персонажей за пределами основной многоязычной плоскости, например!

0 голосов
/ 23 февраля 2010

Вы можете перебирать каждый символ в тексте, проверяя каждый из них на наличие разрывов слов. Следующий пример делает это, считая каждую китайскую / японскую / корейскую (CJK) иероглиф как одно слово и обрабатывая все буквенно-цифровые строки как отдельные слова.

Некоторые заметки о моей реализации:

  1. Вероятно, неправильно обрабатываются акцентированные символы. Они, вероятно, вызовут разрывы слов. Вы можете изменить wordBreakRegEx, чтобы исправить это.

  2. cjkRegEx не включает некоторые из более эзотерических диапазонов кодовых точек, поскольку для ссылки им требуется 5 шестнадцатеричных цифр, а механизм регулярных выражений JavaScript, похоже, не позволяет вам этого делать. Но вам, вероятно, не нужно беспокоиться об этом, поскольку я даже не думаю, что большинство шрифтов включают их.

  3. Я сознательно оставил японцев Хирагана и Катакана из 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 очень полезна для изучения CJK в юникоде. Также, конечно, домашняя страница Unicode содержит множество информации.

0 голосов
/ 23 февраля 2010

Я думаю, вы хотите перебрать все символы и увеличивать счетчик каждый раз, когда текущий символ находится в другом слове (в соответствии с вашим определением), чем предыдущий.

...