используя javascript, как я могу посчитать смесь азиатских символов и английских слов

Мне нужно взять строку смешанных азиатских символов (сейчас предположим, что это только китайские иероглифы или японские иероглифы/хирагана/катакана) и «буквенно-цифровые» (т.

1) считать каждого азиатского ПЕРСОНАЖА за 1; 2) считать каждое буквенно-цифровое СЛОВО за 1;

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

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


моя единственная идея до сих пор заключается в использовании:

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

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

Идеи?


person user224513    schedule 23.02.2010    source источник
comment
Вы не можете отличить азиатский символ от других многобайтовых символов.   -  person shinkou    schedule 23.02.2010
comment
Что вы можете. Ведь у них разные ценности.   -  person Annabelle    schedule 23.02.2010
comment
Всем спасибо. На самом деле мы остановились на: var charArray=val.match(/\w+|[^.,0-9, ゙, ゚ ]/g); оповещение (charArray.length); Нас не интересовало количество азиатских слов, нам нужно было количество символов плюс количество буквенно-цифровых слов. Я думаю, нам нужно будет добавить несколько кодов исключения, но это хорошее начало.   -  person user224513    schedule 24.02.2010


Ответы (3)


К сожалению, RegExp в JavaScript не поддерживает классы символов 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;

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

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

person bobince    schedule 23.02.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. Кроме того, на главной странице Unicode есть много информации.

person Annabelle    schedule 23.02.2010
comment
Не очень полезно, за исключением, например, псевдокода. 1) В примере реализации отсутствует закрывающая скобка в конце цикла for, что полностью его нарушает. 2) Если вы это исправите, английские слова будут считаться неправильно. 3) Он также неправильно считает японские слова, потому что автор пропустил хирагану и катакану. - person fotoflo; 22.11.2015

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

person Thilo    schedule 23.02.2010