使可变长度列表可翻译

时间:2013-09-11 21:32:45

标签: php internationalization

我想显示数组中的值列表,并让它可以翻译。我选择的翻译方法是gettext。我想要做的一个例子就是变成一个可变长度的数组,如:

$array = ('apple', 'plum', 'watermelon', [...]);

加入apple, plum and watermelon之类的字符串。

仅使用英语进行操作不会有问题,但可以翻译是因为其他语言可能不一定使用逗号来分隔值和/或可能没有单词“和”,而在第二个语句之间没有逗号和最后的价值观。如果我知道数组总是有3个值,我可以很容易地做到:

sprintf(gettext("%s, %s and %s"), $array[0], $array[1], $array[2]);

问题是阵列的长度可能不同。如何从可变长度数组中创建可翻译列表?

修改

也许我没有说清楚,但其他语言可能会以不同方式处理列表。例如,一种语言可能会显示像1 and 2, 3, 4这样的列表,另一种语言可能会显示为1, 2, 3, 4,另一种可能会在列表之前和之后显示额外的内容等等。

4 个答案:

答案 0 :(得分:0)

您可以执行以下操作:

  • 循环播放您的数组
  • 检查迭代是否是最后一次
  • 如果是,则将and添加到变量

代码:

function makeTrans($array) 
{
    $str = '';
    for ($i=0; $i < count($array); $i++) { 
        if($i == count($array) - 1) {
            $str .= "and ".$array[$i];
        }
        else {
            $str .= $array[$i]." ";
        }
    }
    return $str;
}

用法:

$array = array('apple', 'plum', 'watermelon', 'foo', 'bar', 'baz', 'baq');
echo makeTrans($array);

输出:

apple plum watermelon foo bar baz and baq

See it in action!

答案 1 :(得分:0)

这可能会有所帮助,但是就预先知道使用哪种类型的分隔符和胶水而言,它可能有一个列表并且能够将该语言作为参考来使用哪一个?

<?php

/**
 * @author - Sephedo
 * @for - Mike @ Stackoverflow
 * @question - http://stackoverflow.com/questions/18751650/making-a-variable-length-list-translatable
 */

echo arr2str( array('apple', 'banana', 'peach', 'pear', 'orange') );

// This function will convert the array to a formatted string.
function arr2str( array $array, $separator = ', ', $glue = ' and ' )
{
    if( count( $array ) == 1 ) return (string) $array; // If there is only one item return the item.

    $last = array_pop( $array ); // get the last element of the array and remove from the array.

    return implode( $separator, $array ) . "$glue$last"; // implode the array by the seperator and add the last element.
}
?>

这将返回

string 'apple, banana, peach, pear  and orange' (length=38)

答案 2 :(得分:0)

我想到这样做的一种方式是这样的:

function array_to_str($array) {
    $two_values = _("%s and %s");
    $three_values = _("%s, %s and %s");
    $separator = _(", ");
    if (count($array) == 1) {
        return $array[0];
    }
    if (count($array) == 2) {
        return sprintf($two_values, $array[0], $array[1]);
    }
    $prev = '';
    for ($i = 0; $i < count($array) - 2; $i++) {
        $prev .= $array[$i];
        if ($i < count($array) - 3) {
            $prev .= $separator;
        }
    }
    return sprintf(
        $three_values, 
        $prev,
        $array[count($array) - 2], 
        $array[count($array) - 1]
    );
}

$arrays[] = array('apple');
$arrays[] = array('apple', 'plum');
$arrays[] = array('apple', 'plum', 'watermelon');
$arrays[] = array('apple', 'plum', 'watermelon', 'lemon');
foreach ($arrays as $array) {
    echo array_to_str($array) . PHP_EOL;
}

这将输出:

apple
apple and plum
apple, plum and watermelon
apple, plum, watermelon and lemon

如果语言使用列表格式1 and 2, 3, 4, 5, 6,翻译人员可以通过翻译来克服这个问题

$three_values = "%3$s and %2$s, %1$s"; 

不幸的是这样做,列表将出现故障。该字符串将输出6 and 5, 1, 2, 3, 4

但是,通过Google翻译中当前定义的语言, none 会将“和”的位置更改为除了倒数第二个位置之外的任何内容。从左到右阅读时,从右到左的语言将它放在第一个元素之后,但由于它从右到左,它实际上处于正确的(倒数第二个)位置。

使用此方法还可以克服以非标准方式显示其列表的语言:

(Korean) 1, 2, 3, 4             <-- only commas are used
(Italian) 1, 2, 3 e 4,          <-- extra comma at the end
(Chinese) 1,2,3和4的           <-- extra 的 at the end
(Hungarian) Az 1., 2., 3. és 4. <-- extra A at the beginning for 2 numbers, Az at the beginning for 3 or more numbers

最后一个可以使用上面的函数完成:

$two_values = "A %s és %s";
$three_values = "Az %s, %s és %s";
$separator = ", ";

假设您的数字格式正确,则会输出:

A 1. és 2.
Az 1., 2. és 3.
Az 1., 2., 3. és 4.

答案 3 :(得分:0)

如果您想更改分隔符的位置,请尝试修改此版本

<?php

/**
 * @author - Sephedo
 * @for - Mike @ Stackoverflow
 * @question - http://stackoverflow.com/questions/18751650/making-a-variable-length-list-translatable
 */

var_dump( arr2str( array('apple', 'banana', 'peach', 'pear', 'orange') ) );
var_dump( arr2str( array('apple', 'banana', 'peach', 'pear', 'orange'), 1 ) );
var_dump( arr2str( array('apple', 'banana', 'peach', 'pear', 'orange'), 3 ) );
var_dump( arr2str( array('apple', 'banana', 'peach', 'pear', 'orange'), 4 ) );

// @array - the array to parse
// @pos - the position to put the glue
// @separator - aka the comma separator
// @glue - aka the and word
function arr2str( array $array, $pos=null, $separator = ', ', $glue = ' and ' )
{
    if( count( $array ) == 1 ) return (string) $array; // If there is only one item return the item.

    if( is_null( $pos ) ) $pos = count( $array ) - 1; // get the default and position aka last.

    $start = array_slice( $array, 0, $pos ); $end = array_slice( $array, $pos, count( $array ) + 1 );

    return implode( $separator, $start ) . $glue . implode( $separator, $end );
}

?>

这将导致

string 'apple, banana, peach, pear and orange' (length=37)
string 'apple and banana, peach, pear, orange' (length=37)
string 'apple, banana, peach and pear, orange' (length=37)
string 'apple, banana, peach, pear and orange' (length=37)