問題是絕對新的我,但土耳其語有 i
:一個點上i
,另一個沒有點ı
。 i
都有相應的資本I
:İ
和I
。所有的信息與許多其他語言沒有什麼不同。主要問題在於選擇4個字符的Unicode表示法:土耳其字符i
和I
使用相同的代碼,如拉丁字符:U+0069
和U+0049
。只有字符ı
和İ
將映射到U+0131
和U+0130
(請參閱here)。這種映射使得不可能實現不區分大小寫的比較或JavaScript函數.toUpperCase()
和.toLowerCase()
。如果輸入的文本包含拉丁文字母i
,那麼函數.toUpperCase()
應將其轉換爲I
,但它對土耳其語不正確,應改爲İ
。 .toLowerCase()
對於土耳其文應該產生ı
,對於英文文本應該產生i
。
因此,第一個重要信息:如果不知道輸入語言,就不可能實現一個通用版本的不區分大小寫的比較。
好的。現在回到問題。如何在土耳其語文本中實現不區分大小寫的搜索?在版本4.7.1中更改了jqGrid的許可協議後,我繼續開發免費版本(在MIT和GPL v2許可下),名稱爲free jqGrid。我在免費jqGrid的第一個版本中實現了許多新功能:4.8版。 the wiki article中描述的「自定義過濾」功能可以幫助實施。
基於我創建的功能the following demo。在實現期間,我在免費jqGrid的代碼中進行了一些小錯誤修復。所以我在演示中使用GitHub(http://rawgit.com/free-jqgrid/jqGrid/master/js/jquery.jqgrid.src.js
)的最新源代碼(有關URL,請閱讀wiki)。
我用下面的選項中的jqGrid
ignoreCase: false,
customSortOperations: {
teq: {
operand: "==",
text: "Turkish insensitive \"equal\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData === searchValue;
}
},
tne: {
operand: "!=",
text: "Turkish insensitive \"not equal\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData !== searchValue;
}
},
tbw: {
operand: "^",
text: "Turkish insensitive \"begins with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.substr(0,searchValue.length) === searchValue;
}
},
tbn: {
operand: "!^",
text: "Turkish insensitive \"does not begin with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.substr(0,searchValue.length) !== searchValue;
}
},
tew: {
operand: "|",
text: "Turkish insensitive \"end with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(),
searchLength = searchValue.length;
return fieldData.substr(fieldData.length-searchLength,searchLength) === searchValue;
}
},
ten: {
operand: "[email protected]",
text: "Turkish insensitive \"does not end with\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase(),
searchLength = searchValue.length;
return fieldData.substr(fieldData.length-searchLength,searchLength) !== searchValue;
}
},
tcn: {
operand: "~",
text: "Turkish insensitive \"contains\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.indexOf(searchValue,0) >= 0;
}
},
tnc: {
operand: "!~",
text: "Turkish insensitive \"does not contain\"",
filter: function (options) {
var fieldData = String(options.item[options.cmName]).replace(/i/g,'İ').toUpperCase(),
searchValue = options.searchValue.replace(/i/g,'İ').toUpperCase();
return fieldData.indexOf(searchValue,0) < 0;
}
}
}
選項customSortOperations
定義新的自定義操作不區分大小寫土耳其文本的比較。要使用該選項一個只需要指定searchoptions
的操作對於其中包含土耳其文本列:
searchoptions: { sopt: ["tcn", "tnc", "teq", "tne", "tbw", "tbn", "tew", "ten"] }
由於過濾使用「TCN」(Turkish insensitive "contains"
)作爲默認過濾操作的結果。如果使用filterToolbar
的searchOperators: true
選項,則可以選擇其他搜索操作。我希望所有上述定製比較操作都是正確的,並且可以在土耳其網格中使用。
更新2:我發現了一個更多的興趣執行選項:支持參數的方法localeCompare。我測試了谷歌瀏覽器
"i".localeCompare("İ", "tr", { sensitivity: "base" }) === 0
"i".localeCompare("I", "tr", { sensitivity: "base" }) === 1
"ı".localeCompare("I", "tr", { sensitivity: "base" }) === 0
"ı".localeCompare("İ", "tr", { sensitivity: "base" }) === -1
或
"i".localeCompare("İ", "tr", { sensitivity: "accent" }) === 0
"i".localeCompare("I", "tr", { sensitivity: "accent" }) === 1
"ı".localeCompare("I", "tr", { sensitivity: "accent" }) === 0
"ı".localeCompare("İ", "tr", { sensitivity: "accent" }) === -1
但在IE11相同的測試失敗相反the information about the browser compatibility。以上所有呼叫localeCompare
在IE11中返回0
。可以使用其他值sensitivity
來獲得預期結果。對於localeCompare
以上的調用,IE9會返回1或-1。我想它只考慮第一個參數並忽略"tr", { sensitivity: "base" }
部分。在Chrome結果看起來那麼
一個具有相同的結果在Firefox
但不是在IE11
一個更多的選擇將是使用The ECMAScript Internationalization API類Intl.Collator (見ecma-402和here),像
new Intl.Collator("tr", { sensitivity: "base" }).compare("i", "İ")
例如,但IE瀏覽器似乎是在情況也好不了多少。
以任何方式,我想可以通過包含瀏覽器檢測部分來改進上述解決方案,該部分爲比較的實現選擇閉包,以及稍後在customSortOperations
之內使用最佳實現。不過上面的代碼工作安全,但可能原因不那麼高雅。
非常感謝@Oleg。 – 2015-04-07 05:21:11
@MuratFurkanSönmez:不客氣! – Oleg 2015-04-07 07:24:03