将字符串拆分为字母数组 - 双字符字母 PHP

3

我需要将一个字符串分割成字母数组。问题在于,在我的语言(克罗地亚语)中,也有双字符字母(例如lj、nj、dž)。

因此,像ljubičicajecvijet这样的字符串应该被分割成一个类似以下的数组:

Array
(
    [0] => lj
    [1] => u
    [2] => b
    [3] => i
    [4] => č
    [5] => i
    [6] => c
    [7] => a
    [8] => j
    [9] => e
    [10] => c
    [11] => v
    [12] => i
    [13] => j
    [14] => e
    [15] => t
)

以下是一个包含克罗地亚字母的数组列表(我也包括了英文字母)。

$alphabet= array(
            'a', 'b', 'c',
            'č', 'ć', 'd',
            'dž', 'đ', 'e',
            'f', 'g', 'h',
            'i', 'j', 'k',
            'l', 'lj', 'm',
            'n', 'nj', 'o',
            'p', 'q', 'r',
            's', 'š', 't',
            'u', 'v', 'w',
            'x', 'y', 'z', 'ž'
          );

1
那么,如果要分别判断字符串中是否包含字符lj,而不是字符lj,你会怎么做呢? - Mihai Matei
我在考虑按字符数对字母进行分类。首先将单词按字符数分割,然后再按单个字符的字母分割。不幸的是,这也会带来问题。 - dodo254
2个回答

1
您可以使用这种解决方案:

数据:

$text = 'ljubičicajecviježdžt';

$alphabet = [
            'a', 'b', 'c',
            'č', 'ć', 'd',
            'dž', 'đ', 'e',
            'f', 'g', 'h',
            'i', 'j', 'k',
            'l', 'lj', 'm',
            'n', 'nj', 'o',
            'p', 'q', 'r',
            's', 'š', 't',
            'u', 'v', 'w',
            'x', 'y', 'z', 'ž'
];

1. 按长度排序,以使双字母出现在开头。

// 2 letters first
usort($alphabet, function($a, $b) {
    if( mb_strlen($a) != mb_strlen($b) )
        return mb_strlen($a) < mb_strlen($b);
    else
        return $a > $b;
});

var_dump($alphabet);

2. 最后,拆分。 我使用了preg_split函数,并使用preg_quote来保护该函数。

// split
$alphabet = array_map('preg_quote', $alphabet); // protect preg_split
$pattern = implode('|', $alphabet); // 'dž|lj|nj|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|ć|č|đ|š|ž'

var_dump($pattern);

var_dump( preg_split('`(' . $pattern . ')`si', $text, null, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) );

结果如下 :)

array (size=18)
  0 => string 'lj' (length=2)
  1 => string 'u' (length=1)
  2 => string 'b' (length=1)
  3 => string 'i' (length=1)
  4 => string 'č' (length=2)
  5 => string 'i' (length=1)
  6 => string 'c' (length=1)
  7 => string 'a' (length=1)
  8 => string 'j' (length=1)
  9 => string 'e' (length=1)
  10 => string 'c' (length=1)
  11 => string 'v' (length=1)
  12 => string 'i' (length=1)
  13 => string 'j' (length=1)
  14 => string 'e' (length=1)
  15 => string 'ž' (length=2)
  16 => string 'dž' (length=3)
  17 => string 't' (length=1)

非常好的解决方案,非常感谢你的答复 :D - dodo254
我只是想问一下。在玩弄你的代码时,我尝试将你的usort更改为: usort($alphabet, function($a, $b) { return mb_strlen($a) < mb_strlen($b); }); 这种方式似乎也可以正常工作。你对此有什么看法? - dodo254
当然可以 :) 它能工作是因为这是相同的“行为”。第二个检查是根据它们的大小排序字符 ddd > aa > ab > zz > a > b > c。在这里不需要。这是一个“漂亮的功能” :p - Georges O.
确实很棒 :D 顺便问一下,既然你已经解决了这个问题,我想知道你是否可以尝试解决另一个问题。这个问题涉及或可能涉及你已经在这里提供的代码片段。它有点更加复杂(至少对我来说是这样)。实际上,我想使用这段代码来对单词数组进行排序。起初我以为这段代码就足够了,但我遇到了更多的问题。现在,如果你不想解决它,那也没关系...但我敢你试试。:P :D [http://stackoverflow.com/questions/40330383/sort-array-of-words-non-english-letters-double-character-letters-php] - dodo254

1
或者你可以使用这个来确保每个双倍数都被检查匹配,并且如果它匹配(你可以将$alphabet数组减少到只匹配我的解决方案中的那些双字符:
<?php

ini_set('display_errors',1); // this should be commented out in production environments
error_reporting(E_ALL); // this should be commented out in production environments


$string = 'ljubičicajecvijet';

$alphabet= [
            'a', 'b', 'c',
            'č', 'ć', 'd',
            'dž', 'đ', 'e',
            'f', 'g', 'h',
            'i', 'j', 'k',
            'l', 'lj', 'm',
            'n', 'nj', 'o',
            'p', 'q', 'r',
            's', 'š', 't',
            'u', 'v', 'w',
            'x', 'y', 'z', 'ž'
          ];

function str_split_unicode($str, $length = 1) {
    $tmp = preg_split('~~u', $str, -1, PREG_SPLIT_NO_EMPTY);
    if ($length > 1) {
        $chunks = array_chunk($tmp, $length);
        foreach ($chunks as $i => $chunk) {
            $chunks[$i] = join('', (array) $chunk);
        }
        $tmp = $chunks;
    }
    return $tmp;
}

$new_array = str_split_unicode($string,2);

foreach ($new_array as $key => $value) {
    if (strlen($value) == 2) {
        if (in_array($value, $alphabet)) {
            $test[$key] = $value;
            unset($new_array[$key]);
        }
    }
}

$new_array = str_split_unicode(join('',$new_array)); 

foreach ($test as $key => $value) {
    array_splice($new_array, $key, 0, $value);  
}

print_r($new_array);

?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接