使用javascript计算textarea中的字节数

使用javascript计算textarea中的字节数,javascript,utf-8,Javascript,Utf 8,当UTF8使用javascript编码时,我需要计算文本区域的字节长度。你知道我该怎么做吗 谢谢 我一直在问自己同样的问题。这是我偶然发现的最好的答案: encodeURIComponent(text).replace(/%[A-F\d]{2}/g, 'U').length 以下是代码片段: <script type="text/javascript"> function checkLength() { var countMe = document.getElement

当UTF8使用javascript编码时,我需要计算文本区域的字节长度。你知道我该怎么做吗


谢谢

我一直在问自己同样的问题。这是我偶然发现的最好的答案:

encodeURIComponent(text).replace(/%[A-F\d]{2}/g, 'U').length

以下是代码片段:

<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)
 }

函数checkLength(){
var countMe=document.getElementById(“someText”).value
var escapedStr=encodeURI(countMe)
if(escapedStr.indexOf(“%”)=-1){
var count=escapedStr.split(“%”)。长度-1
if(count==0)count++//反常情况;不可能发生在真正的UTF-8中
var tmp=escapedStr.length-(计数*3)
计数=计数+tmp
}否则{
count=转义str.length
}
警报(escapedStr+”:大小为“+计数)
}

但该链接包含一个可供使用的实例。“encodeURI(STRING)”是这里的构建块,但也可以查看encodeURIComponent(STRING)(正如前面的答案中已经指出的)以确定哪一个适合您的需要


关于

[2020年6月:因其返回而被替换]

大多数现代JS环境(浏览器和节点)现在都支持UTF8,可以按如下方式使用UTF8字节计数:

const textEncoder = new TextEncoder();
textEncoder.encode('⤀⦀⨀').length; // => 9

这与下面其他答案中提到的
getUTF8Length()
函数相同,但应该足以满足除最苛刻的用例之外的所有用例。此外,它还可以利用经过良好测试、维护良好且可移植的标准API。

如果字符串中有非bmp字符,则会稍微复杂一些

因为javascript进行UTF-16编码,“字符”是一个2字节堆栈(16位),所以所有多字节字符(3个或更多字节)都不起作用:

    <script type="text/javascript">
        var nonBmpString = "foo€";
        console.log( nonBmpString.length );
        // will output 5
    </script>

结合各种答案,以下方法应该快速准确,并避免出现可能导致encodeURIComponent()出错的无效代理项对问题:

函数getUTF8Length(s){ var-len=0; 对于(变量i=0;iencodeURI(text).split(/%…|./).length-1
将字节长度计数函数添加到字符串中

String.prototype.Blength = function() {
    var arr = this.match(/[^\x00-\xff]/ig);
    return  arr == null ? this.length : this.length + arr.length;
}
然后,您可以使用.Blength()来获取大小简单点怎么样:

unescape(encodeURIComponent(utf8text)).length
诀窍在于encodeURIComponent似乎可以处理字符,而unescape可以处理字节。

请尝试以下操作:

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;
}
功能b(c){
var n=0;

对于(i=0;iset
metautf-8
just&it's OK

<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">

我认为这个实现是不正确的,因为它会对代理项字符计数两次:一次是在遇到高代理项时,一次是在遇到低代理项时。例如,下面返回6:getUTF8Length(String.fromCharCode(0xD800,0xDC00)),尽管这表示一个字符(我必须承认,我不知道是哪一个,我只是组合了2个代理字符代码…。不过我不是unicode方面的专家…@Didier L,是的,你是对的!应该将其添加到案例列表中并加以说明。这是非常巧妙的。问题之一是,如果字符串包含无效的代理模式,它将抛出。例如,
encodeURIComponent('\ud800a')
。需要注意的是。如何在textarea中插入包含无效代理模式的字符串?我尝试将文本'\ud800a'插入到该文本中(它在内部使用
encodeURI
-函数对插入的文本进行编码)但无法重现这样的错误情况-相反,我看到:
document.getElementsByTagName(“textarea”)[0]。value===“\\ud800a”
。用于计算UTF-8字符串的长度。@LauriOherd:(非常!)此处响应延迟,但为了回答您的问题,textareas将接受无效字符串。例如,
textarea.value='\ud800'&&encodeURIComponent(textarea.value)
将抛出(至少在Chrome中会).Hi Frank,我使用了你的方法,它对多字节字符字符串有效。我有一个文本区域,当用户键入时,我需要在其中计算字符/字节数。我尝试了按键事件,但在复制/粘贴时它没有被触发。你能建议一些可靠有效的方法来计算用户键入时的字节数吗?我需要显示一个计数像“300左…”谢谢和问候,Nadeemt这里没有必要使用
else if(charCode<67108864){}
bit和其后的
else
。Unicode在U+10FFFF处停止,不可能在JavaScript中表示非Unicode代码点。根据RFC3629规范,这是正确的。但原始规范最多允许6个字节字符。我不确定应该遵守哪种实现,但我想说我是这样做的“这是正确的解决方案。@DaanBiesterbos:JavaScript使用UTF-16,但它不能表示代码点(不存在的代码点)无论如何,在U+10FFFF以上。@frank_neff使用本机浏览器函数有什么问题吗?
unescape
函数是我遇到了一个糟糕的设计情况,我被迫显式地计算字节数并进行处理。在上述代码段的顶部,我还必须添加对下一行字符的处理,因为它们也是2个字节。@RBz您是否参考误入NEL(U+0085)字符?这个函数应该正确地将其计数为
0x7f
。不管怎样,现在大多数JS环境都支持
textcoder
API。请参阅我最近对上面接受的答案所做的编辑。我不确定这是如何工作的,但如果我按enter键,这个代码段会将其计数为1。我阅读了earlier chrome将其视为2,现在他们已将其修复为反映1。然而,对我来说,它必须计为2,因为后端数据库将其视为2。@RBz请注意,Unicode中的行终止字符数量可能惊人。有些编码为一个字节,有些编码为两个字节。因此,这实际上取决于特定的字符(s) 已使用/预期。请参阅。
String.prototype.Blength = function() {
    var arr = this.match(/[^\x00-\xff]/ig);
    return  arr == null ? this.length : this.length + arr.length;
}
unescape(encodeURIComponent(utf8text)).length
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;
}
<meta charset="UTF-8">
<meta http-equiv="content-type" content="text/html;charset=utf-8">
if($mytext.length > 10){
 // its okkk :)
}