use*_*287 9 javascript node.js
我正在与一个接受最大 5KB 字符串的 api 交互。
我想将一个可能超过 5KB 的字符串分成小于 5KB 的块。
然后我打算将每个传递smaller-than-5kb-string给 api 端点,并在所有请求完成后执行进一步的操作,可能使用类似的东西:
await Promise.all([get_thing_from_api(string_1), get_thing_from_api(string_2), get_thing_from_api(string_3)])
Run Code Online (Sandbox Code Playgroud)
我读过字符串中的字符可以在 1 - 4 个字节之间。
因此,要计算以字节为单位的字符串长度,我们可以使用:
// in Node, string is UTF-8
Buffer.byteLength("here is some text");
// in Javascript
new Blob(["here is some text"]).size
Run Code Online (Sandbox Code Playgroud)
来源:
https : //stackoverflow.com/a/56026151
/sf/answers/3657785841/
我搜索"how to split strings into chunks of a certain size"与将字符串拆分为特定字符长度而不是字节长度的字符串相关的返回结果,例如:
// in Node, string is UTF-8
Buffer.byteLength("here is some text");
// in Javascript
new Blob(["here is some text"]).size
Run Code Online (Sandbox Code Playgroud)
来源:
https : //stackoverflow.com/a/7033662
/sf/answers/438168041/
https://gist.github.com/hendriklammers/5231994
题
有没有办法将字符串拆分为特定字节长度的字符串?
我可以:
但更喜欢更准确的解决方案。
我很想知道 Node 和普通 JavaScript 解决方案,如果它们存在的话。
编辑
这种计算方法byteLength可能会有所帮助 - 通过迭代字符串中的字符,获取它们的字符代码并相应地递增byteLength:
var my_string = "1234 5 678905";
console.log(my_string.match(/.{1,2}/g));
// ["12", "34", " 5", " 6", "78", "90", "5"]Run Code Online (Sandbox Code Playgroud)
来源:https : //stackoverflow.com/a/23329386
function byteLength(str) {
// returns the byte length of an utf8 string
var s = str.length;
for (var i=str.length-1; i>=0; i--) {
var code = str.charCodeAt(i);
if (code > 0x7f && code <= 0x7ff) s++;
else if (code > 0x7ff && code <= 0xffff) s+=2;
if (code >= 0xDC00 && code <= 0xDFFF) i--; //trail surrogate
}
return s;
}
Run Code Online (Sandbox Code Playgroud)
但正如@trincot 在评论中指出的那样,处理多字节字符的正确方法是什么?我怎样才能确保块在空格上分开(以免“分开”一个词?)
有关缓冲区的更多信息:https : //nodejs.org/api/buffer.html#buffer_buffer
编辑
如果它可以帮助其他人理解已接受答案中的绝妙逻辑,下面的代码片段是我制作的大量评论版本,因此我可以更好地理解它。
var buf = Buffer.from('Hey! ?');
// <Buffer 48 65 79 21 20 d1 84>
buf.length // 7
buf.toString().charCodeAt(0) // 72
buf.toString().charCodeAt(5) // 1092
buf.toString().charCodeAt(6) // NaN
buf[0] // 72
for (let i = 0; i < buf.length; i++) {
console.log(buf[i]);
}
// 72 101 121 33 32 209 132 undefined
buf.slice(0,5).toString() // 'Hey! '
buf.slice(0,6).toString() // 'Hey! ?'
buf.slice(0,7).toString() // 'Hey! ?'
Run Code Online (Sandbox Code Playgroud)
使用Buffer似乎确实是正确的方向。鉴于:
Buffer原型具有indexOf和lastIndexOf方法,以及...您可以按照以下步骤进行:
function chunk(s, maxBytes) {
let buf = Buffer.from(s);
const result = [];
while (buf.length) {
let i = buf.lastIndexOf(32, maxBytes+1);
// If no space found, try forward search
if (i < 0) i = buf.indexOf(32, maxBytes);
// If there's no space at all, take the whole string
if (i < 0) i = buf.length;
// This is a safe cut-off point; never half-way a multi-byte
result.push(buf.slice(0, i).toString());
buf = buf.slice(i+1); // Skip space (if any)
}
return result;
}
console.log(chunk("Hey there! € 100 to pay", 12));
// -> [ 'Hey there!', '€ 100 to', 'pay' ]
Run Code Online (Sandbox Code Playgroud)
您可以考虑将其扩展为还查找 TAB、LF 或 CR 作为拆分字符。如果是这样,并且您的输入文本可能具有 CRLF 序列,您还需要检测这些序列以避免在块中出现孤立的 CR 或 LF 字符。
您可以将上述函数转换为生成器,以便您控制何时开始处理以获取下一个块:
function * chunk(s, maxBytes) {
let buf = Buffer.from(s);
while (buf.length) {
let i = buf.lastIndexOf(32, maxBytes+1);
// If no space found, try forward search
if (i < 0) i = buf.indexOf(32, maxBytes);
// If there's no space at all, take all
if (i < 0) i = buf.length;
// This is a safe cut-off point; never half-way a multi-byte
yield buf.slice(0, i).toString();
buf = buf.slice(i+1); // Skip space (if any)
}
}
for (let s of chunk("Hey there! € 100 to pay", 12)) console.log(s);
Run Code Online (Sandbox Code Playgroud)
Buffer特定于节点。然而,浏览器实现了TextEncoderandTextDecoder,这会导致类似的代码:
function chunk(s, maxBytes) {
let buf = Buffer.from(s);
const result = [];
while (buf.length) {
let i = buf.lastIndexOf(32, maxBytes+1);
// If no space found, try forward search
if (i < 0) i = buf.indexOf(32, maxBytes);
// If there's no space at all, take the whole string
if (i < 0) i = buf.length;
// This is a safe cut-off point; never half-way a multi-byte
result.push(buf.slice(0, i).toString());
buf = buf.slice(i+1); // Skip space (if any)
}
return result;
}
console.log(chunk("Hey there! € 100 to pay", 12));
// -> [ 'Hey there!', '€ 100 to', 'pay' ]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4409 次 |
| 最近记录: |