代码之家  ›  专栏  ›  技术社区  ›  Timur Gafforov

希伯来文字母比较

  •  0
  • Timur Gafforov  · 技术社区  · 6 年前

    我试着把希伯来语单词拆分成字母,得到相应符号的索引。我已经设置了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=>'ת‬',
    );
    

    我向这样的页面发送post请求:

    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);
    

    我收到了一个邮寄请求,我正试图获得每个对应希伯来文字母的钥匙:

    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.试图在相同的文件中以相同的方式输出俄语字母,效果很好。看起来问题不在于编码

    2 回复  |  直到 6 年前
        1
  •  1
  •   Justin T.    6 年前

    正如@Rei在他的回答中指出的,您当前的符号数组存在一个问题。修剪完符号后,我注意到有多个字符的七(7)个值有一个标准字符和三个字符中的一个 指向

    1. 希伯来语点DAGESH或MAPIQ( ּ
    2. ׁ )
    3. 希伯来文点SIN-DOT( ׂ )

    我编写了一些代码,将希伯来语字符转换为十进制数字HTML编码值。如果其中一个 如果遇到值,它将与数组中的下一个字符组合以匹配符号之一。以下代码对我来说很好:

    <?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
    //    )
    
        2
  •  2
  •   Rei    6 年前

    代码的问题是符号数组。

    代码的最后一部分尝试将1个符号(字符)与中的元素匹配 $id_symbols 问题是这些元素都不是一个符号。 它们每个都是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型 ,仍有7个元素的宽度为2个符号。 解决这个问题的方法是:必须用它们的单符号版本来替换它们。

    \u05da\u05bc \ufb3a . 看到了吗 https://codepoints.net/U+FB3A

    我相信你能处理剩下的6个符号。