Количество байтов в textarea с использованием javascript
Мне нужно подсчитать, сколько времени в байтах текстовое поле, когда UTF8 кодируется с помощью javascript. Любая идея, как я это сделаю?
спасибо!
Ответы
Ответ 1
edit: как указал Didier-l, эта функция не учитывает суррогатные символы.
Ответ broofa должен правильно считать суррогаты, см. fooobar.com/questions/339586/....
Я тестировал две предложенные версии здесь, а также наивную реализацию:
getUTF8Length: function(string) {
var utf8length = 0;
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utf8length++;
}
else if((c > 127) && (c < 2048)) {
utf8length = utf8length+2;
}
else {
utf8length = utf8length+3;
}
}
return utf8length;
}
В результате моя версия немного быстрее в firefox и значительно быстрее в хром (~ 30x), чем в опубликованных версиях.
Ответ 2
encodeURIComponent(text).replace(/%[A-F\d]{2}/g, 'U').length
Ответ 3
Если у вас есть символы non-bmp в вашей строке, это немного сложнее...
Поскольку javascript кодирует UTF-16, а "символ" - это 2-байтовый (16 бит), все многобайтовые символы (3 и более байтов) не будут работать:
<script type="text/javascript">
var nonBmpString = "foo€";
console.log( nonBmpString.length );
// will output 5
</script>
Символ "€" имеет длину 3 байта (24 бит). Javascript интерпретирует его как 2 символа, потому что в JS символ является 16-битным блоком.
Итак, чтобы правильно получить байтес смешанной строки, мы должны закодировать нашу собственную функцию fixedCharCodeAt();
function fixedCharCodeAt(str, idx) {
idx = idx || 0;
var code = str.charCodeAt(idx);
var hi, low;
if (0xD800 <= code && code <= 0xDBFF) { // High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
hi = code;
low = str.charCodeAt(idx + 1);
if (isNaN(low)) {
throw 'Kein gültiges Schriftzeichen oder Speicherfehler!';
}
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
}
if (0xDC00 <= code && code <= 0xDFFF) { // Low surrogate
// We return false to allow loops to skip this iteration since should have already handled high surrogate above in the previous iteration
return false;
/*hi = str.charCodeAt(idx-1);
low = code;
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;*/
}
return code;
}
Теперь мы можем подсчитать байты...
function countUtf8(str) {
var result = 0;
for (var n = 0; n < str.length; n++) {
var charCode = fixedCharCodeAt(str, n);
if (typeof charCode === "number") {
if (charCode < 128) {
result = result + 1;
} else if (charCode < 2048) {
result = result + 2;
} else if (charCode < 65536) {
result = result + 3;
} else if (charCode < 2097152) {
result = result + 4;
} else if (charCode < 67108864) {
result = result + 5;
} else {
result = result + 6;
}
}
}
return result;
}
Кстати...
Вы не должны использовать метод encodeURI, потому что он является собственной функцией браузера;)
Больше вещей:
Приветствия
frankneff.ch / @frank_neff
Ответ 4
Объединяя различные ответы, следующий метод должен быть быстрым и точным и избегать проблем с недействительными суррогатными парами, которые могут вызвать ошибки в encodeURIComponent():
function getUTF8Length(s) {
var len = 0;
for (var i = 0; i < s.length; i++) {
var code = s.charCodeAt(i);
if (code <= 0x7f) {
len += 1;
} else if (code <= 0x7ff) {
len += 2;
} else if (code >= 0xd800 && code <= 0xdfff) {
// Surrogate pair: These take 4 bytes in UTF-8 and 2 chars in UCS-2
// (Assume next char is the other [valid] half and just skip it)
len += 4; i++;
} else if (code < 0xffff) {
len += 3;
} else {
len += 4;
}
}
return len;
}
Ответ 5
Добавить функцию подсчета длины байта в строку
String.prototype.Blength = function() {
var arr = this.match(/[^\x00-\xff]/ig);
return arr == null ? this.length : this.length + arr.length;
}
то вы можете использовать .Blength(), чтобы получить размер
Ответ 6
Как насчет простого:
unescape(encodeURIComponent(utf8text)).length
Фокус в том, что encodeURIComponent, похоже, работает с символами, а unescape работает с байтами.
Ответ 7
Я спрашивал себя то же самое. Это лучший ответ, который я наткнулся на:
http://www.inter-locale.com/demos/countBytes.html
Вот фрагмент кода:
<script type="text/javascript">
function checkLength() {
var countMe = document.getElementById("someText").value
var escapedStr = encodeURI(countMe)
if (escapedStr.indexOf("%") != -1) {
var count = escapedStr.split("%").length - 1
if (count == 0) count++ //perverse case; can't happen with real UTF-8
var tmp = escapedStr.length - (count * 3)
count = count + tmp
} else {
count = escapedStr.length
}
alert(escapedStr + ": size is " + count)
}
но ссылка содержит живой пример ее воспроизведения. "encodeURI (STRING)" - это строительный блок здесь, но также посмотрите на encodeURIComponent (STRING) (как уже указано в предыдущем ответе), чтобы узнать, какой из них соответствует вашим потребностям.
Привет
Ответ 8
encodeURI(text).split(/%..|./).length - 1
Ответ 9
установите meta UTF-8
как раз и это ОК!
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
и js:
if($mytext.length > 10){
// its okkk :)
}
Ответ 10
Попробуйте следующее:
function b(c) {
var n=0;
for (i=0;i<c.length;i++) {
p = c.charCodeAt(i);
if (p<128) {
n++;
} else if (p<2048) {
n+=2;
} else {
n+=3;
}
}return n;
}