2009-10-04 1 views
7

Я использую API Zemanta, который принимает до 8 КБ текста за звонок. Я извлекаю текст для отправки в Земанта с веб-страниц с помощью JavaScript, поэтому я ищу функцию, которая усекает мой текст ровно в 8 КБ.Использование JavaScript для усечения текста до определенного размера (8 КБ)

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

Можно ли предположить, что 8 КБ текста составляет 8 192 символов, и соответственно усекать? (1 байт на символ, 1024 символа на КБ, 8 КБ = 8 192 байта/символов) Или это неточно или верно только при определенных обстоятельствах?

Есть ли более элегантный способ усечения строки на основе фактического размера файла?

+0

Возможно, вам захочется проверить, имеет ли текст, с которым вы имеете дело, определенную кодировку, например. UTF-8, ASCII и т. Д.? Если вы уверены, что текст содержит только однобайтовые символы, усечение будет более простым. Вы отделите некоторую гибкость. Что касается Zemanta рассматривает 8KB как 8192 байта или 8000 байт, почему бы вам не проверить его самостоятельно? –

+0

Спасибо, o.k.w.Я думаю, что Доминик прав, что этот текст (вероятно, UTF-8) потенциально займет несколько байтов на символ, поэтому измерение на основе количества символов будет невозможно. – Bungle

ответ

9

Если вы используете однобайтовое кодирование, да, 8192 символов = 8192 байта. Если вы используете UTF-16, 8192 символа (*) = 4096 байт.

(На самом деле 8192 кодовых точек, что является немного другим делом, в лице ставленников, но давайте не будет беспокоиться о том, что, поскольку JavaScript не делает.)

Если вы используете UTF-8, есть быстрый трюк вы можете использовать, чтобы реализовать UTF-8 кодер/декодер в JS с минимальным кодом:

function toBytesUTF8(chars) { 
    return unescape(encodeURIComponent(chars)); 
} 
function fromBytesUTF8(bytes) { 
    return decodeURIComponent(escape(bytes)); 
} 

Теперь вы можете укоротить с:

function truncateByBytesUTF8(chars, n) { 
    var bytes= toBytesUTF8(chars).substring(0, n); 
    while (true) { 
     try { 
      return fromBytesUTF8(bytes); 
     } catch(e) {}; 
     bytes= bytes.substring(0, bytes.length-1); 
    } 
} 

(причина для примерки с что если вы усекаете байты в середине многобайтовой последовательности символов, вы получите недопустимый поток UTF-8, а decodeURIComponent будет жаловаться.)

Если это еще одно многобайтовое кодирование, такое как Shift-JIS или Big5, ты сам по себе.

+1

Это именно то, что я искал - работает как шарм! Спасибо, бобин. Просто довольно примечательно для потомков - я немного плотный, поэтому мне потребовалось несколько минут, чтобы понять, что переменные «unicodecharacters» и «utf8bytes» в ваших функциях предназначены только для объяснения и должны фактически соответствовать аргументам для работы (т.е. оба должны быть заменены на «s» в двух более коротких функциях). Еще раз спасибо! – Bungle

+1

Упс! Опасности вырезания и вставки, есть. Та для улова! – bobince

2

Нет, небезопасно предположить, что 8 Кбайт текста составляет 8192 символа, так как в некоторых символьных кодировках каждый символ занимает multiple bytes.

Если вы читаете данные из файлов, не можете ли вы просто захватить размер файла? Или прочитать его в кусках 8KB?

+0

Спасибо, Доминик. Я собираю этот текст из документа с использованием метода .innerText() JavaScript. Вместо файла .txt или чего-то еще, поэтому я не уверен, что есть способ указать «дать мне 8 КБ данные "- это в идеале то, что я ищу. – Bungle

1

Как говорит Dominic, кодировка символов проблема - однако, если вы можете действительно гарантирует, что вы будете иметь дело только с 8-битных символов (маловероятно, но возможно) или принимать 16-битные символы и ограничивать себя в половине доступное пространство, то есть 4096 символов, тогда вы можете попробовать это.

Плохая идея полагаться на JS для этого, потому что это может быть тривиально изменено или проигнорировано, и у вас есть сложности с escape-символами и кодировкой, чтобы иметь дело, например. Лучше использовать JS в качестве фильтра с первой вероятностью и использовать любой серверный язык, который у вас есть (который также откроет сжатие).

+0

Спасибо, annakata - похоже, что функции bobince будут работать в моем случае. Zemanta на самом деле просто отсекает любой текст по лимиту 8 КБ, поэтому меня меньше беспокоит то, что в конечном итоге доходит до их API (в отличие от экономии полосы пропускания, конечно), так как максимальная производительность в этом случае будет ограничена по крайней мере, примерно 8 КБ на стороне клиента. – Bungle

Смежные вопросы