更准确地说,我需要知道是否(如果可能的话,如何)找出给定字符串是否具有双字节字符。基本上,我需要打开一个弹出窗口来显示包含双字节字符(如中文或日语)的给定文本。在这种情况下,我们需要调整窗口大小,以使其比英语或ASCII所需的大小更大。
有人知道吗?
更准确地说,我需要知道是否(如果可能的话,如何)找出给定字符串是否具有双字节字符。基本上,我需要打开一个弹出窗口来显示包含双字节字符(如中文或日语)的给定文本。在这种情况下,我们需要调整窗口大小,以使其比英语或ASCII所需的大小更大。
有人知道吗?
我使用了mikesamuel关于这个问题的回答。但是我发现,可能由于这个表单的原因,在正确运行此代码时,应该只有一个反斜杠转义 u
,例如\u
而不是\\u
。
function containsNonLatinCodepoints(s) {
return /[^\u0000-\u00ff]/.test(s);
}
对我来说有效 :)
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;
}
这可能不像您期望的那样快速。
我已经对前两个回答中的两个函数进行了基准测试,并想与大家分享结果。以下是我使用的测试代码:
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);
}
如果第一个字符是中文(如果整个文本都是中文,则很可能如此),则该函数将快速返回。否则,它将运行正则表达式,这仍然比逐个检查每个字符要快。
function containsNonLatinCodepoints(s) {
return /[^\u0000-\u00ff]/.test(s);
}
function isDoubleByte(str) {
for (var i = 0, n = str.length; i < n; i++) {
if (str.charCodeAt( i ) > 255) { return true; }
}
return false;
}
o = document.getElementById("test");
document.defaultView.getComputedStyle(o,"").getPropertyValue("height"))
window.resizeTo(document.body.clientWidth, document.body.clientHeight);
var ctx = canvas.getContext('2d')
)来获取文本宽度度量。var text_width = ctx.measureText(text).width;
我不确定这种方法在Unicode字符方面的效果如何,而且很遗憾,measureText
方法目前只返回宽度。 - WebWanderer