我正在尝试先按照它的值对数组进行排序,然后按它的键进行排序,但是php对波斯语字符的效果不佳。
波斯语字母表类似于阿拉伯字母,除了一些额外的字符,如'گچپژک'和PHP在波斯语字母表中排序阿拉伯字母方面做得很好,但其余的不在他们的顺序中。
例如
$str = 'ا ب پ ت ث ج چ ح خ د ذ ر ز ژ ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی';
$arr = explode(' ', $str);
将按正确的字母顺序创建一个包含所有波斯语字母的数组($arr
)。如果我将其洗牌并使用asort
函数如下:
shuffle($arr);
asort($arr);
var_dump($arr);
它会像这样结束:
array
2 => string 'ا'
1 => string 'ب'
22 => string 'ت'
29 => string 'ث'
20 => string 'ج'
12 => string 'ح'
21 => string 'خ'
18 => string 'د'
6 => string 'ذ'
3 => string 'ر'
27 => string 'ز'
17 => string 'ص'
11 => string 'ض'
25 => string 'ط'
5 => string 'ظ'
16 => string 'ع'
8 => string 'غ'
26 => string 'ف'
14 => string 'ق'
9 => string 'ل'
0 => string 'م'
7 => string 'ن'
10 => string 'ه'
28 => string 'و'
24 => string 'پ'
23 => string 'چ'
13 => string 'ژ'
19 => string 'ک'
4 => string 'گ'
15 => string 'ی'
哪个错了!
第24项应在第1项之后,第23项应在20之后,依此类推。
如何编写与PHP自己的排序函数类似的函数?或者有可能让PHP函数适用于波斯字符?
答案 0 :(得分:4)
我编写了以下函数来返回任何给定字符的UTF-8代码点:
function utf8_ord($str) {
$str = (string) $str;
$ord = ord($str);
$ord_b = decbin($ord);
if (strlen($ord_b) <= 7)
return $ord;
$len = strlen(strstr($ord_b, "0", true));
if ($len < 2 || $len > 4 || strlen($str) < $len)
return false;
$val = substr($ord_b, $len + 1);
for ($i = 1; $i < $len; $i++) {
$ord_b = decbin(ord($str[$i]));
if ($ord_b[0].$ord_b[1] != "10")
return false;
$val. = substr($ord_b, 2);
}
$val = bindec($val);
return (($val > 0x10FFFF) ? null : $val);
}
现在让我们找出数组中字符的UTF-8代码点:
$str = 'ا ب پ ت ث ج چ ح خ د ذ ر ز ژ ص ض ط ظ ع غ ف ق ک گ ل م ن و ه ی';
$arr = explode(' ', $str);
print_r(array_map("utf8_ord", $arr));
输出将是:
Array
(
[0] => 1575
[1] => 1576
[2] => 1662
[3] => 1578
[4] => 1579
[5] => 1580
[6] => 1670
[7] => 1581
[8] => 1582
[9] => 1583
[10] => 1584
[11] => 1585
[12] => 1586
[13] => 1688
[14] => 1589
[15] => 1590
[16] => 1591
[17] => 1592
[18] => 1593
[19] => 1594
[20] => 1601
[21] => 1602
[22] => 1705
[23] => 1711
[24] => 1604
[25] => 1605
[26] => 1606
[27] => 1608
[28] => 1607
[29] => 1740
)
它清楚地表明字符的顺序不正确,需要进行排序。我不知道波斯语,所以我无法确定UTF-8波斯语字母表是否有错。但我只能说PHP正在正常工作。
答案 1 :(得分:0)
我为波斯数组创建了一个自定义javascript排序函数:
var alphabets = ["ا", "ب", "پ", "ت", "ث", "ج", "چ", "ح", "خ", "د",
"ذ", "ر", "ز", "ژ", "س", "ش", "ص", "ض", "ط", "ظ", "ع", "غ",
"ف", "ق", "ک", "گ", "ل", "م", "ن", "و", "ه", "ی"];
function PersianOrder(){
var persianArrray = ["ایمان", "محمدرضا", "ژوله", "چمدان", "پدرام", "پاشی","پاشا"];
persianArrray.sort(function (a, b) {
return CharCompare(a, b, 0);
});
}
function CharCompare(a, b, index) {
if (index == a.length || index == b.length)
return 0;
var aChar = alphabets.indexOf(a.charAt(index));
var bChar = alphabets.indexOf(b.charAt(index));
if (aChar != bChar)
return aChar - bChar
else
return CharCompare(a,b,index+1)
}
我希望这个功能可以帮助你
答案 2 :(得分:0)
很好地获取可以使用的可用语言环境
print_r(ResourceBundle::getLocales(''));
我有'fa'
和'fa_IR'
可用,但'fa_IR'
仍然返回false,所以我使用'fa'
来测试它:
setlocale(LC_ALL, 'fa');
asort($arr, SORT_LOCALE_STRING);
var_dump($arr);
但是这还没有按照正确的顺序排序......
所以在更多的谷歌搜索后,最终为我排序Unicode波斯语字母表的解决方案是使用Collator类:
$col = new \Collator('fa_IR');
$col->asort($arr);
var_dump($arr);
我知道问题已经过时了,但这可能仍然有助于新人来到这里寻找这个问题的答案。
答案 3 :(得分:0)
要按波斯字符对数组排序,首先请注意Unicode标准中的某些字符未正确对齐。 在这种情况下,我的建议是创建一个规则的波斯字符数组,并根据该数组排列主题数组。 例如:
function persianSort($item1, $item2){
$persian_characters = [
1 => 'ا',
2 => 'ب',
3 => 'پ',
4 => 'ت',
5 => 'ث',
6 => 'ج',
7 => 'چ',
8 => 'ح',
9 => 'خ',
10 => 'د',
11 => 'ذ',
12 => 'ر',
13 => 'ز',
14 => 'ژ',
15 => 'س',
16 => 'ش',
17 => 'ص',
18 => 'ض',
19 => 'ط',
20 => 'ظ',
21 => 'ع',
22 => 'غ',
23 => 'ف',
24 => 'ق',
25 => 'ک',
26 => 'گ',
27 => 'ل',
28 => 'م',
29 => 'ن',
30 => 'و',
31 => 'ه',
32 => 'ی',
];
if(substr($item1,0,2) == substr($item2,0,2))
return persianSort(substr($item1,2), substr($item2,2));
return array_search( substr($item1,0,2), $persian_characters) < array_search( substr($item2,0,2), $persian_characters) ? -1: 1;
}
$states = ['گیلان', 'گرگان', 'یزد', 'سمنان', 'تهران', 'اردبیل', 'کرمان', 'چهار محال بختیاری', 'مشهد', 'اصفهان', 'قم', 'آستارا'];
usort($states, "persianSort");
print_r($states);
上面的代码对伊朗省名的无序数组进行排序。上面代码的输出如下:
Array
(
[0] => اردبیل
[1] => اصفهان
[2] => تهران
[3] => چهار محال بختیاری
[4] => سمنان
[5] => قم
[6] => کرمان
[7] => گرگان
[8] => گیلان
[9] => مشهد
[10] => یزد
)
答案 4 :(得分:0)
这是按波斯字母对每个类型数组进行排序的简单方法:
在代码中使用setlocale(LC_ALL,'fa_IR')和SORT_LOCALE_STRING很重要。
多维度数组的示例:
$arr = [
[
"name"=> "پژمان",
"family"=> "رضایی",
"age"=> "20",
],
[
"name"=> "بابک",
"family"=> "قاسمی",
"age"=> "25",
],
[
"name"=> "محمد",
"family"=> "حسینی",
"age"=> "19",
],
[
"name"=> "هاشم",
"family"=> "مقدم",
"age"=> "28",
],
[
"name"=> "آفرینش",
"family"=> "دلربا",
"age"=> "18",
],
[
"name"=> "مونا",
"family"=> "محمدی",
"age"=> "26",
],
];
setlocale(LC_ALL, 'fa_IR');
$faColumns = array_column($arr, 'name');
array_multisort($faColumns, SORT_ASC, SORT_LOCALE_STRING , $arr);
print_r($arr);
索引数组示例
$arr1 = ["پژمان","بابک","محمد","هاشم","آفرینش","مونا"];
setlocale(LC_ALL, 'fa_IR');
asort($arr1, SORT_LOCALE_STRING);
print_r($arr1);
答案 5 :(得分:0)
因为我发现 utf8 表的排序不像波斯字母表的顺序,所以 php 必须对波斯语单词进行排序,因为它们必须排序
<?php
function persianCmp($a, $b) {
$per = [
"آ", "ا", "ب", "پ",
"ت", "ث", "ج", "چ",
"ح", "خ", "د", "ذ",
"ر", "ز", "ژ", "س",
"ش", "ص", "ض", "ط",
"ظ", "ع", "غ", "ف",
"ق", "ک", "گ", "ل",
"م", "ن", "و", "ه",
"ی"
];
$per= array_flip($per);
$a = $per[mb_strcut($a,0,2)];
$b = $per[mb_strcut($b,0,2)];
//echo "\na:".$a." b:".$b;
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$persianWords = [ "هدیه","حمیدرضا","غلامی","بروجنی","آیه","چرم","بسته"];
var_dump($persianWords);
usort($persianWords, "persianCmp");
var_dump($persianWords);
/*array(7) {
[0]=>string(8) "هدیه"
[1]=>string(14) "حمیدرضا"
[2]=>string(10) "غلامی"
[3]=> string(12) "بروجنی"
[4]=> string(6) "آیه"
[5]=> string(6) "چرم"
[6]=> string(8) "بسته"
}
array(7) {
[0]=> string(6) "آیه"
[1]=> string(12) "بروجنی"
[2]=> string(8) "بسته"
[3]=> string(6) "چرم"
[4]=> string(14) "حمیدرضا"
[5]=> string(10) "غلامی"
[6]=> string(8) "هدیه"
*/