当前位置:  开发笔记 > 编程语言 > 正文

如何查找特定字符串是否具有unicode字符(尤其是双字节字符)

如何解决《如何查找特定字符串是否具有unicode字符(尤其是双字节字符)》经验,为你挑选了4个好方法。

更确切地说,我需要知道(如果可能的话)我是否可以找到给定字符串是否具有双字节字符.基本上,我需要打开一个弹出窗口来显示一个给定的文本,它可以包含双字节字符,如中文或日文.在这种情况下,我们需要调整窗口大小,而不是英文或ASCII.有人有线索吗?



1> 小智..:

我在这个问题上使用了mikesamuel的答案.但是我注意到也许是因为这种形式在它之前应该只有一个逃避斜杠u,例如\u并且不能\\u使其正常工作.

function containsNonLatinCodepoints(s) {
    return /[^\u0000-\u00ff]/.test(s);
}

适合我:)



2> pcorcoran..:

JavaScript将文本内部保存为UCS-2,它可以编码相当广泛的Unicode子集.

但这与你的问题没有密切关系.一种解决方案可能是遍历字符串并检查每个位置的字符代码:

function isDoubleByte(str) {
    for (var i = 0, n = str.length; i < n; i++) {
        if (str.charCodeAt( i ) > 255) { return true; }
    }
    return false;
}

这可能没有您想要的那么快.



3> laurent..:

我在顶部答案中对这两个函数进行了基准测试,并认为我会分享结果.这是我使用的测试代码:

const text1 = `The Chinese Wikipedia was established along with 12 other Wikipedias in May 2001. ?????????????????????????????????????1785??1850???1839??`;

const regex = /[^\u0000-\u00ff]/; // Small performance gain from pre-compiling the regex
function containsNonLatinCodepoints(s) {
    return regex.test(s);
}

function isDoubleByte(str) {
    for (var i = 0, n = str.length; i < n; i++) {
        if (str.charCodeAt( i ) > 255) { return true; }
    }
    return false;
}

function benchmark(fn, str) {
    let startTime = new Date();
    for (let i = 0; i < 10000000; i++) {
        fn(str);
    }   
    let endTime = new Date();

    return endTime.getTime() - startTime.getTime();
}

console.info('isDoubleByte => ' + benchmark(isDoubleByte, text1));
console.info('containsNonLatinCodepoints => ' + benchmark(containsNonLatinCodepoints, text1));

在运行时,我得到了:

isDoubleByte => 2421
containsNonLatinCodepoints => 868

因此对于这个特定的字符串,正则表达式解决方案的速度提高了约3倍.

但请注意,对于第一个字符为unicode的字符串,立即isDoubleByte()返回,因此比正则表达式(仍然具有正则表达式的开销)快得多.

例如对于字符串??,我得到了这些结果:

isDoubleByte => 51
containsNonLatinCodepoints => 288

为了获得两全其美,最好将两者结合起来:

var regex = /[^\u0000-\u00ff]/; // Small performance gain from pre-compiling the regex
function containsDoubleByte(str) {
    if (!str.length) return false;
    if (str.charCodeAt(0) > 255) return true;
    return regex.test(str);
}

在这种情况下,如果第一个字符是中文(这可能是整个文本是中文),该功能将很快并立即返回.如果没有,它将运行正则表达式,这仍然比单独检查每个字符更快.



4> JasonTrue..:

实际上,所有字符都是Unicode,至少从Javascript引擎的角度来看.

不幸的是,仅仅存在特定Unicode范围内的字符将不足以确定您需要更多空间.有许多字符占用的空间大致与其他具有远远高于ASCII范围的Unicode代码点的字符相同.印刷引号,带变音符号的字符,某些标点符号和各种货币符号都在低ASCII范围之外,并且分配在Unicode基本多语言平面上非常不同的位置.

通常,我所参与的项目选择为所有语言提供额外的空间,或者有时使用javascript来确定具有自动滚动条css属性的窗口是否实际上具有高度会触发滚动条的内容.

如果检测到CJK字符的存在或计数足以确定您需要一些额外的空间,则可以使用以下范围构建正则表达式:[\ u3300\u9fff\uf900-\ufaff],并使用用于提取匹配字符数的计数.(这有点过于粗糙,并且错过了所有非BMP案例,可能会排除其他一些相关范围,并且很可能包括一些不相关的字符,但这是一个起点).

同样,你只能在没有全文渲染引擎的情况下管理粗略的启发式,因为你真正想要的是类似GDI的MeasureString(或任何其他文本渲染引擎的等价物).我已经有一段时间了,但我认为最接近的HTML/DOM等价物是在div上设置宽度并请求高度(剪切和粘贴重用,如果这包含错误,请道歉):

o = document.getElementById("test");

document.defaultView.getComputedStyle(o,"").getPropertyValue("height"))

推荐阅读
女女的家_747
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有