在PHP中检测字符串中的字符串方向

时间:2013-12-31 18:19:13

标签: php

我正在使用php-gd创建一些文本,但文本编码和方向存在问题 我使用rtl语言的阿拉伯语,同一图像中还会有额外的英语短语。

问题:

imagettftext($image, 18, 0, 317, 141,$font_color, 'breeco.ttf', $Arabic->utf8Glyphs($friends[0]['name']));

如果文本是英文“ltr”,它的x位置为317,这是正确的 但是当它处于rtl时,它将具有相同的317 x位置且不正确

无论如何都要检测字符串的rtl?

2 个答案:

答案 0 :(得分:5)

这实际上比它应该更棘手。每个Unicode字符都有告诉我们它是RTL还是LTR字符的信息,但我没有看到在PHP中读取此信息的方法 - 而是需要在Unicode字符表中查找此信息。

我在下面汇总了一个效率很低的解决方案,但如果您需要更强大的功能,我建议您查看此PHP implementation of Stringprep。该库还将检查字符串的有效性,例如它可以强制执行诸如“在同一个字符串中不混合使用RTL和LTR字符”之类的规则。但是,它是为准备用于互联网协议的字符串而不是标准文本而设计的,因此它所施加的限制可能会妨碍简单地使用它来检查文本方向。

感谢this StackOverflow答案,了解有关获取Unicode数据的位置以及如何解释的信息。

首先,我们可以创建一个文件,其中只包含具有双向属性的字符“R”或“AL”(RandALCat),它存储在Unicode data的第5个字段中。此命令从该URL获取数据,删除第5个字段中没有AL或R的字符,将恢复的十六进制代码填充为6个字符,并将其保存在名为RandALCat.txt的文件中。

curl http://www.unicode.org/Public/6.0.0/ucd/UnicodeData.txt |  \
    egrep -e "([^;]*;){4}(AL|R);.*" | \
    awk -F";" '{ printf("%06s\n", $1) }' > RandALCat.txt

然后我们可以在一个函数中使用这个文件来测试字符串中的每个字符:

<?php

function isRTL($testString) {

    $RandALCat = file('RandALCat.txt', FILE_IGNORE_NEW_LINES);
    $codePoints = unpack('V*', iconv('UTF-8', 'UTF-32LE', $testString));

    foreach ($codePoints as $codePoint) {
        $hexCode = strtoupper(str_pad(dechex($codePoint), 6, '0', STR_PAD_LEFT));
        if (array_search($hexCode, $RandALCat)) {
            return true;
        }
    }

    return false;

}

$englishText = 'Hello';
$arabicText = 'السلام عليكم';

var_dump(isRTL($englishText));
var_dump(isRTL($arabicText));

如果将其保存为test.php或其他内容然后运行它,您应该看到此输出:

$ php -q test.php
bool(false)
bool(true)

答案 1 :(得分:1)

您可以使用以下正则表达式

$rtlChar = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';

我从其中一个Twitter库中借用了Java Script版本。所以你的功能看起来像,

function isRtl($value) {
    $rtlChar = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';
    return preg_match($rtlChar, $value) != 0;
}