9

我想比較JavaScript中兩個相同的字符串,但等號運算符==返回false。一個字符串包含特殊字符(例如丹麥語å)。比較unicode字符時Javascript字符串比較失敗

JavaScript代碼:

var filenameFromJS = "Designhåndbog.pdf"; 
var filenameFromServer = "Designhåndbog.pdf"; 

print(filenameFromJS == filenameFromServer); // This prints false why? 

解決方案 什麼工作對我來說是unicode正常化slevithan指出。

我分出我原來的jsfiddle來製作一個使用slevithan建議的規範化庫的版本。鏈接:http://jsfiddle.net/GWZ8j/1/

+0

查看有關''=='與'===這個http://stackoverflow.com/questions/359494文章/ javascript-vs -do-matter-which-equal-operator-i-use – Steve

+4

@Steve當兩個操作數的類型相同時,使用鬆散或嚴格比較無關緊要。 – PointedEars

回答

10

與其他人在這裏所說的不同,這與編碼無關。相反,您的兩個字符串使用不同的代碼點來呈現相同的視覺字符。

爲了正確解決這個問題,您需要在比較它們之前對兩個字符串執行Unicode規範化。不幸的是,JavaScript沒有內置此功能。下面是一個JavaScript庫,可以爲您執行規範化:https://github.com/walling/unorm

+1

哦,我希望不會得到這個答案:-)我只是想念這個明顯的,並不需要一個庫來完成這個簡單的任務。謝謝你的回答,我會試一試。 – tougher

+0

你是對的,我錯過了'CC 8A'是'U + 30A COMBINING RING ABOVE'的UTF-8代碼序列,前面加上'a'。另一個字符串具有'C3 A5',它以UTF-8編碼'U + 00E5 LATIN小字母A WITH RING ABOVE'。 IIRC,Mac OS更喜歡組合字符,而其他操作系統更喜歡單字形形式。應該可以讓服務器轉換任何一個,但是,因此不需要大的客戶端庫。 – PointedEars

+0

PointedEars,這不一定是可能的或理想的。例如,您可能不想爲了執行字符串比較而往返服務器,或者您可能正在服務器上使用JavaScript。 @Tougher,有一個建議將Unicode規範化添加到未來版本的JavaScript中。參見[strawman:unicode_normalization](http://wiki.ecmascript.org/doku.php?id=strawman:unicode_normalization)。 – slevithan

1

UTF-8是一件複雜的事情。該字符集有兩個不同的字符代碼,如á,é等。正如您已經在URL編碼版本中看到的,其中字符的HEX字節在兩個版本中都不相同。

有關更多信息,請參閱this答案。

+0

JFTR:Unicode是_not_ UTF-8。 Unicode是字符集和幾種編碼的標準; UTF-8是這些編碼之一。 – PointedEars

+0

@PointedEars固定。 – user2428118

+0

現在你在說UTF-8是一個字符集。不是這樣。我也相當肯定你的前提是錯誤的:UTF-8代碼序列不能以0xCC開頭。 – PointedEars

5

在以下情況下JavaScript等於運算符==將顯示爲失敗。在所有情況下,這都是程序員錯誤。不是JavaScript中的錯誤。

  1. 這兩個字符串不包含相同的字符數和序列。

  2. 在一個字符串之前,之內或之後有空格或換行符。在兩者上使用trim()運算符並仔細查看兩個字符串。

  3. 令人驚訝的類型轉換。程序員正在比較不兼容的數據類型。

  4. 有unicode字符看起來與其他unicode字符相同,但實際上是不同的unicode字符。

+0

+1,因爲這個答案比接受的答案更具信息性,並且不包含nodeJS或jQuery的內容。 – unexist

+0

在這種情況下,編號4是罪魁禍首 – vahanpwns

+0

不同的unicode規範化不是關於不同的字符,而是指不同的unicode代碼點序列被用來指代相同的字符。 – James

0

我有同樣的問題。

添加

<meta charset="UTF-8"> 

到HTML文件固定的問題。

在我的情況下,模板引擎正在將json字符串烘焙到HTML文件中。這個字符串是unicode。

雖然模板也是一個unicode文件,但JS引擎將我寫入模板的字符串視爲拉丁字母編碼的字符串,直到我添加了meta標籤。

我比較輸入字符串的JSON對象之一的項目(location.title == "Mühle"