使用 javascript 的子字符串法语文本替换特殊字符

Substring French text using javascript replaces the special characters

由于法语特殊字符,我不能做子字符串。由于法语中的特殊字符,我得到的字符串通常比指定的数字多。

这是我在进行一些搜索后使用的方法。我从 Whosebug 中选择了转换和 byteLength 函数,有些是我错过了我选择这些的线程。这种方法的问题在于它替换了特殊字符。我怎样才能保持特殊字符的完整性?

  1. 将字符串转换为字节数组
  2. 检查每个字节的长度并计算

最终这个脚本会在Boomi内部使用。

法语文本示例

SVP remplacer 3 lumière de néons brûlées. Deux néons sont situés dans le bureau de la cliente et dans le desk room. Le dernier est une ampoule neon et c'est située dans le lobby. Le plafond est de hauteur standard

在运行通过脚本后,它变成了

SVP remplacer 3 lumière de néons brûlées. Deux néons sont situés dans le bureau de la cliente et dans le desk room. Le dernier est une ampoule neon et c'est située dans le lobby.

JS Fiddle

https://jsfiddle.net/learningjsfiddle/0no1t9k8/2/

来电

var newFrench = stringTrim(frenchText, 200);

这里是帮助完成所有这些的函数。

var stringToUtf8ByteArray = function(str) {
            // TODO(user): Use native implementations if/when available
            var out = [], p = 0;
            for (var i = 0; i < str.length; i++) {
                var c = str.charCodeAt(i);
                if (c < 128) {
                    out[p++] = c;
                } else if (c < 2048) {
                    out[p++] = (c >> 6) | 192;
                    out[p++] = (c & 63) | 128;
                } else if (((c & 0xFC00) == 0xD800) && (i + 1) < str.length && ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) {
                    // Surrogate Pair
                    c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF);
                    out[p++] = (c >> 18) | 240;
                    out[p++] = ((c >> 12) & 63) | 128;
                    out[p++] = ((c >> 6) & 63) | 128;
                    out[p++] = (c & 63) | 128;
                } else{
                    out[p++] = (c >> 12) | 224;
                    out[p++] = ((c >> 6) & 63) | 128;
                    out[p++] = (c & 63) | 128;
                }
            }
            return out;
        };

        var byteLength = function(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;
        }

        var stringTrim = function(str, maxLength){
            //convert to byte array
            var arr = stringToUtf8ByteArray(str);
            if(arr.length <= maxLength)
                return str;

            //slice upto maxLength
            var arrNew = arr.slice(0, maxLength);
            //check each char to make sure that french chars are properly picked
            var lengthChar = 0;
            var newVal = "";
            for (i=0; i<maxLength; i++){
                var singleChar = String.fromCharCode(arrNew[i]);
                lengthChar += byteLength(singleChar);
                if(lengthChar <= maxLength)
                    newVal += singleChar;
            }
            return newVal;
        }

更新 1: 这是一个新的 fiddle 并且它保持字符完好无损。我只使用上面的 byteLength。看起来这将是解决方案,除非有人指出我有更好的处理方法。

https://jsfiddle.net/learningjsfiddle/0no1t9k8/27/

var byteFrench = french;
var byteFrenchLength = byteLength(byteFrench);
if (byteFrenchLength > lengthAllowed){
    var newLength = lengthAllowed - (byteFrenchLength-lengthAllowed); //removing extra chars
    byteFrench = byteFrench.substr(0, newLength);
}
document.getElementById('logSubstr').innerHTML = '[' + byteFrenchLength + '] new length ['+ byteLength(byteFrench) +']' + byteFrench;
var byteLength = function(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;
        }


        var subStringTrim = function(str, maxLength){
            if(!hasValue(str) || !hasValue(maxLength) || maxLength <= 0)
                return str;

            var strByteLength = byteLength(str);
            if(strByteLength <= maxLength)
                return str;

            //pick upto maxlength
            str = str.substr(0, maxLength);

            //check the length again and then do sub string by calculating max newLength. This is important for french chars. 
            strByteLength = byteLength(str);
            if(strByteLength <= maxLength)
                return str; //english chars will get returned here

            //removing extra chars for other than english
            var newLength = maxLength - (strByteLength-maxLength); 
            if(newLength > 0)
                str = str.substr(0, newLength);

            return str;
        }