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

Ahm*_*tef 0 php

我正在使用php-gd创建一些文本,但是文本编码和方向存在问题我使用的是阿尔法语言,这是rtl语言,并且在同一图像中会有额外的英语短语.

问题:

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

如果文本是英文"ltr",它将具有317的x位置并且它是正确的但是当它在rtl中时它将具有相同的317 x位置并且它是不正确的

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

mad*_*vid 5

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

我在下面提出了一个相当低效的解决方案,但如果你需要更强大的东西,我建议你看看这个Stringprep的PHP实现.该库还将检查字符串的有效性,例如,它可以强制执行诸如"在同一字符串中不混合RTL和LTR字符"之类的规则.但是,它是为准备用于互联网协议的字符串而不是标准文本而设计的,因此它所施加的限制可能会妨碍简单地使用它来检查文本方向.

由于这个计算器回答有关在哪里得到的Unicode数据,以及如何解释信息.

首先,我们可以创建一个文件,其中只包含具有双向属性的字符"R"或"AL"(RandALCat),它存储在Unicode数据的第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
Run Code Online (Sandbox Code Playgroud)

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

<?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));
Run Code Online (Sandbox Code Playgroud)

如果你将它保存为test.php或其他东西然后运行它,你应该看到这个输出:

$ php -q test.php
bool(false)
bool(true)
Run Code Online (Sandbox Code Playgroud)


maq*_*uni 5

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

$rtlChar = '/[\x{0590}-\x{083F}]|[\x{08A0}-\x{08FF}]|[\x{FB1D}-\x{FDFF}]|[\x{FE70}-\x{FEFF}]/u';
Run Code Online (Sandbox Code Playgroud)

我从 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;
}
Run Code Online (Sandbox Code Playgroud)