我正在尝试将希伯来语单词拆分为字母,并获取相应符号的索引。我已经设置了UTF-8标头,并检查了文件的编码实际上是UTF-8。但是由于某些原因,PHP无法正确比较符号,并且不返回所需的符号ID,而如果我输出$ text数组,它将输出正常。我有一系列希伯来字母:
$id_symbols = array(
280=>'א',
281=>'בּ',
282=>'ב',
283=>'ג',
284=>'ד',
285=>'ה',
286=>'ו',
287=>'ז',
288=>'ח',
289=>'ט',
290=>'י',
291=>'כּ',
292=>'כ',
293=>'ךּ',
294=>'ך',
295=>'ל',
296=>'מ',
297=>'ם',
298=>'נ',
299=>'ן',
300=>'ס',
301=>'ע',
302=>'פּ',
303=>'פ',
304=>'ף',
305=>'צ',
306=>'ץ',
307=>'ק',
308=>'ר',
309=>'שׁ',
310=>'שׂ',
311=>'תּ',
312=>'ת',
);
我向这样的页面发送发帖请求:
header('Content-type: text/html; charset=utf-8');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://pr.animizer.net/word-api.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
"api_key=some_key&text=מילה&font=arial&font_size=30&fore_color=000000&back_color=FFFFFF&template=1,2,3&speed=4");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close ($ch);
exit($server_output);
已收到POST请求,我正在尝试获取每个对应的希伯来字母的密钥:
function mb_str_split($string) {
$strlen = mb_strlen($string);
while ($strlen) {
$array[] = mb_substr($string,0,1,"UTF-8");
$string = mb_substr($string,1,$strlen,"UTF-8");
$strlen = mb_strlen($string);
}
return $array;
}
$text = mb_str_split($_POST['text']); //splitting text into symbols
foreach($text as $t){
foreach($id_symbols as $key=>$value){
if($value == $t){
$word[] = $key;
}
}
}
print_r($word);
,输出为
Array
(
)
P.S。试图在相同的文件中以相同的方式输出俄语字母,它们工作正常。看起来好像不是编码问题
答案 0 :(得分:2)
您的代码存在问题是符号数组。
代码的最后部分尝试将1个符号(字符)与$id_symbols
中的元素进行匹配。
问题是这些元素都不是1个符号。
它们分别是2个或3个符号,因此它们将永远不匹配。
此代码将向您显示。
foreach($id_symbols as $key => $value) {
echo $key.' '.$value.' '.json_encode($value)."\n";
}
输出:
280 א "\u05d0\u202c"
281 בּ "\u05d1\u05bc\u202c"
282 ב "\u05d1\u202c"
283 ג "\u05d2\u202c"
284 ד "\u05d3\u202c"
285 ה "\u05d4\u202c"
286 ו "\u05d5\u202c"
287 ז "\u05d6\u202c"
288 ח "\u05d7\u202c"
289 ט "\u05d8\u202c"
290 י "\u05d9\u202c"
291 כּ "\u05db\u05bc\u202c"
292 כ "\u05db\u202c"
293 ךּ "\u05da\u05bc\u202c"
294 ך "\u05da\u202c"
295 ל "\u05dc\u202c"
296 מ "\u05de\u202c"
297 ם "\u05dd\u202c"
298 נ "\u05e0\u202c"
299 ן "\u05df\u202c"
300 ס "\u05e1\u202c"
301 ע "\u05e2\u202c"
302 פּ "\u05e4\u05bc\u202c"
303 פ "\u05e4\u202c"
304 ף "\u05e3\u202c"
305 צ "\u05e6\u202c"
306 ץ "\u05e5\u202c"
307 ק "\u05e7\u202c"
308 ר "\u05e8\u202c"
309 שׁ "\u05e9\u05c1\u202c"
310 שׂ "\u05e9\u05c2\u202c"
311 תּ "\u05ea\u05bc\u202c"
312 ת "\u05ea\u202c"
每个反斜杠都应该只有一个,但所有反斜杠都必须有2或3。
第一个问题,它们都被\u202c
终止。
解决此问题的方法很简单:只需删除它们即可。
第二个问题,即使删除了所有\u202c
,仍然有2个符号宽的7个元素。
它们是281、291、293、302、309、310、311。
解决此问题的方法:必须将其替换为单个符号版本。
例如,索引293的元素为\u05da\u05bc
,可以将其替换为\ufb3a
。
参见https://codepoints.net/U+FB3A
我相信您可以处理其余6个符号。
答案 1 :(得分:1)
正如@Rei在他的答案中指出的那样,当前的符号数组存在问题。修剪符号后,我注意到具有不止一个字符的七(7)个值具有标准字符和三个 point 字符之一:
ּ
)ׁ
)ׂ
)我写了一些代码,将希伯来字符转换为十进制数字HTML编码值。如果遇到 point 值之一,它将与数组中的下一个字符组合以匹配您的一个符号。以下代码对我来说效果很好:
<?php
function _uniord($c) {
if (ord($c{0}) >=0 && ord($c{0}) <= 127)
return ord($c{0});
if (ord($c{0}) >= 192 && ord($c{0}) <= 223)
return (ord($c{0})-192)*64 + (ord($c{1})-128);
if (ord($c{0}) >= 224 && ord($c{0}) <= 239)
return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128);
if (ord($c{0}) >= 240 && ord($c{0}) <= 247)
return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128);
if (ord($c{0}) >= 248 && ord($c{0}) <= 251)
return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128);
if (ord($c{0}) >= 252 && ord($c{0}) <= 253)
return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128);
if (ord($c{0}) >= 254 && ord($c{0}) <= 255) // error
return FALSE;
return 0;
}
function mb_str_split($string) {
$strlen = mb_strlen($string);
while ($strlen) {
$array[] = mb_substr($string,-1,1,"UTF-8");
$string = mb_substr($string,0,$strlen-1,"UTF-8");
$strlen = mb_strlen($string);
}
return $array;
}
$hebrewText = $_POST['text'] //"מילה" used in example;
$text = mb_str_split($hebrewText); //splitting text into symbols
$word = [];
$lookupChrs = array(
'1488'=>280,
'14681489'=>281,
'1489'=>282,
'1490'=>283,
'1491'=>284,
'1492'=>285,
'1493'=>286,
'1494'=>287,
'1495'=>288,
'1496'=>289,
'1497'=>290,
'14681499'=>291,
'1499'=>292,
'14681498'=>293,
'1498'=>294,
'1500'=>295,
'1502'=>296,
'1501'=>297,
'1504'=>298,
'1503'=>299,
'1505'=>300,
'1506'=>301,
'14681508'=>302,
'1508'=>303,
'1507'=>304,
'1510'=>305,
'1509'=>306,
'1511'=>307,
'1512'=>308,
'14731513'=>309,
'14741513'=>310,
'14681514'=>311,
'1514'=>312
);
foreach($text as $t){
$lookupChr = _uniord(array_shift($text));
$lookupChr = (string)$lookupChr;
//handle accents (two charactrers instead of one)
if($lookupChr == "1468" || $lookupChr == "1473" || $lookupChr == "1474"){
//accent detected, combine with next character
//echo "\"" . $lookupChr . "\":\"" . _uniord(array_shift($text)) . "\"";
$lookupChr .= _uniord(array_shift($text));
}
if($lookupChr != "0"){
$word[] = $lookupChrs[$lookupChr];
}
}
print_r($word);
//OUTPUT:
// Array
// (
// [0] => 285
// [1] => 295
// [2] => 290
// [3] => 296
// )