2010-11-27 37 views
5

我正在尝试使用JavaScript &正则表达式将数字HTML实体替换为其实际的Unicode字符,例如,使用JavaScript正则表达式将数字HTML实体替换为其实际字符

foo's bar 
→ 
foo's bar 

这是我走到这一步:

"foo's bar".replace(/&#([^\s]*);/g, "$1"); // "foo39s bar" 

所有剩下要做的就是用String.fromCharCode($1)更换号码,但我似乎无法得到它的工作。我怎样才能做到这一点?

回答

8
"foo's bar".replace(/&#(\d+);/g, function(match, match2) {return String.fromCharCode(+match2);}) 
+0

这只是返回``foos bar“`。我错过了什么吗?编辑:哦,显然这是因为`match` =`“'”`而不仅仅是`39`。 – alfonso 2010-11-27 15:23:17

+0

是的,你是正确的,我修复了代码从此 – 2010-11-27 15:25:48

3
"foo's bar".replace(/&#([^\s]*);/g, function(x, y) { return String.fromCharCode(y) }) 

第一个参数(x)是在当前的例子中为 “'”。 y是39.

0

如果你不想定义所有的实体,你可以让浏览器为你做 - 它创建一个空的p元素,写入html并返回它产生的文本。 p元素永远不会添加到文档中。

function translateEntities(string){ 
    var text, p=document.createElement('p'); 
    p.innerHTML=string; 
    text= p.innerText || p.textContent; 
    p.innerHTML=''; 
    return text; 
} 
var s= 'foo's bar'; 
translateEntities(s); 

/* returned value: (String) 
foo's bar 
*/ 
3

除了使用一个回调函数,你可能要考虑为十六进制字符引用添加支持(ሴ)。

此外,fromCharCode可能不够。例如𐤀是对腓尼基字符的有效引用,但由于它位于基本多语言平面之外,并且JavaScript的字符串模型基于UTF-16代码单元,而不是完整的字符代码点,因此fromCharCode(67840)将不起作用。你需要一个UTF-16编码器,例如:

String.fromCharCodePoint= function(/* codepoints */) { 
    var codeunits= []; 
    for (var i= 0; i<arguments.length; i++) { 
     var c= arguments[i]; 
     if (arguments[i]<0x10000) { 
      codeunits.push(arguments[i]); 
     } else if (arguments[i]<0x110000) { 
      c-= 0x10000; 
      codeunits.push((c>>10 & 0x3FF) + 0xD800); 
      codeunits.push((c&0x3FF) + 0xDC00); 
     } 
    } 
    return String.fromCharCode.apply(String, codeunits); 
}; 

function decodeCharacterReferences(s) { 
    return s.replace(/&#(\d+);/g, function(_, n) {; 
     return String.fromCharCodePoint(parseInt(n, 10)); 
    }).replace(/&#x([0-9a-f]+);/gi, function(_, n) { 
     return String.fromCharCodePoint(parseInt(n, 16)); 
    }); 
}; 

alert(decodeCharacterReferences('Hello &#x10900; mum &#67840;!'));