V
V
Vadim2018-08-06 12:27:50
PHP
Vadim, 2018-08-06 12:27:50

How to make a function that correctly handles both Cyrillic and Latin?

Good day. I solve the problem of checking the incoming string for a palindrome (read in both directions: Argentina beckons a black man). I will convert to one register, cut out all unnecessary possible characters through str_replace.

function transformString($string){
            $charsToDelete = ['!', '?', ' ', '.', ',', '-', '—'];
            $string = mb_strtolower($string);
            $string = str_replace($charsToDelete, '', $string);
            return $string;
        }

Then you need to reverse the line. Since strrev messes with the encoding, I decided to split the string into an array using str_split, indicating that it should use 2 bytes when splitting, since utf-8 Cyrillic uses 2 bytes per character, after which I turn the resulting array and again combine it into a string through implode :
function reverseString($string){
            $string = str_split($string,2);
            $string = array_reverse($string);
            $string = implode($string);
            return $string;
        }

Then I compare the converted string with the inverted converted string, and if they are equal, then the input string is a palindrome. And it seems like everything is fine, only if the incoming string is not in Cyrillic, but in Latin, for example "Sum summus mus", then when splitting the string through str_split with the second parameter 2, and in reverse we get "ussmmuummssu". How to solve this problem and write a cross-language function for processing the incoming string?
Full listing:
spoiler
$string = "Аргентина манит негра!";
        function isPalindrom ($string) {
            $textForCheck = transformString($string); 
            $reversedTextForCheck = reverseString($textForCheck);  
            echo $textForCheck.'<br>'; //аргентинаманитнегра
            echo $reversedTextForCheck.'<br>'; //аргентинаманитнегра
            if ($textForCheck === $reversedTextForCheck) {
                echo $string . ' — эта строка палиндром.';
            } else {
                echo "Не полиндром.";
            }
            return $textForCheck;
        };
        function transformString($string){
            $charsToDelete = ['!', '?', ' ', '.', ',', '-', '—'];
            $string = mb_strtolower($string);
            $string = str_replace($charsToDelete, '', $string);
            return $string;
        }

        function reverseString($string){
            $string = str_split($string,2);
            $string = array_reverse($string);
            $string = implode($string);
            return $string;
        }
        isPalindrom($string); // Аргентина манит негра! — эта строка палиндром.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
PrAw, 2018-08-06
@MrDecoy

php.net/manual/ru/function.mb-split.php also
works correctly with Unicode multibyte characters.

N
Nikolay, 2018-08-06
@iNickolay

function mb_strrev ($str) {
    $out = '';
    for ($i = mb_strlen($str); $i>=0; $i--) {
        $r .= mb_substr($str, $i, 1);
    }

    return $out;
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question