Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> mb_strpos не находит пробел 
V
    Опции темы
WebDisaster
Дата 13.1.2016, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 406
Регистрация: 22.6.2007

Репутация: нет
Всего: 19



Доброго дня.

Пытаюсь решить задачу: из полного имени и отчества, которые получаю в одной переменной, нужно сделать инициалы. Чтобы получить второй инициал, пытаюсь читать первый символ после пробела, и столкнулся с тем, что mb_strpos() неправильно определяет позицию пробела в строке. Вся информация в utf-8; php 5.3.13

Не могу понять, в каком месте я затупил, и как сделать правильно. Только больно не бейте, если сможете - php не мой профиль smile 
Спасибо заранее

Код


    $string[] = 'Андрей Васильевич';
    $string[] = 'Тамара Николаевна';
    $string[] = 'Татьяна Александровна';
    
    foreach($string as $initial) {
        $initial    = trim($initial);                    // Удаляем концевые пробелы
        $initial    = preg_replace('/\s+/', ' ', $initial);    // Разные варианты разделения слов заменяем на один пробел
        $pos        = mb_strpos($initial, ' ');            // Ищем позицию пробела в строке "имя отчество"
//        $pos        = mb_strpos($initial, chr(32));        // Тоже не работает так, как хочется
//        $pos        = mb_strpos($initial,  chr(194).chr(160));    // Поиск "неразрывного пробела" - тоже не работает
        echo        $pos . ' - ';                    // Отладочная информация - позиция пробела, которую "нашла" функция mb_strpos()
        $pos        = $pos + 1;                    // Находим позицию первого символа после пробела
        echo        $initial . ' - ';                    // Имя Отчество - 
        $initial_1    = mb_substr($initial, 0, 1, 'utf-8');    // Читаем первый символ в строке
        $initial_1    = mb_strtoupper($initial_1, 'utf-8');    // Переводим в верхний регистр            
        echo        $initial_1 . '.';                // Выводим с точкой в конце
        $initial_2    = mb_substr($initial, $pos, 1, 'utf-8');// Читаем первый символ после пробела
        $initial_2    = mb_strtoupper($initial_2, 'utf-8');    // Переводим в верхний регистр    
        echo        $initial_2 . '.<br />';                // Выводим с точкой в конце
    }




PM MAIL   Вверх
s1lver
Дата 13.1.2016, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 580
Регистрация: 14.12.2007
Где: Россия

Репутация: нет
Всего: нет



А что не так в получившемся выводе?

Код

6 - Андрей Васильевич - А.В.<br />
6 - Тамара Николаевна - Т.Н.<br />
7 - Татьяна Александровна - Т.А.<br />



--------------------
Я собрался жить вечно - пока все идет нормально!
PM MAIL ICQ   Вверх
WebDisaster
Дата 13.1.2016, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 406
Регистрация: 22.6.2007

Репутация: нет
Всего: 19



Гы. Это ещё интересней. У меня выводит только так, причём без вариантов. 

Код

12 - Андрей Васильевич - А.Е.
12 - Тамара Николаевна - Т.Е.
14 - Татьяна Александровна - Т.Д.


Выходит так, что у меня $pos всегда умножен на два  smile 
Видимо, какой-то чудной косяк с php на сервере. Нужно на другом попробовать.


P.S. Попробовал ещё на двух серверах - такая же фигня - (стоят php 5.2.17 и 4.3.9)
Если $pos делить на два - тогда всё ОК. 

s1lver, а ты в какой кодировке файл сохранял, когда всё работало? В utf-8? Или в какой-нибудь однобайтной?
Пока напрашивается такая мысль, что правильно этот код будет работать в однобайтных кодировках, а в utf-8 получаемую позицию пробела нужно делить на 2 )

Это сообщение отредактировал(а) WebDisaster - 13.1.2016, 11:45
PM MAIL   Вверх
ksnk
Дата 13.1.2016, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Нужно явно и всегда указывать внутреннюю кодировку. Для всех mb_ функций. Это делает их сложно применимыми в бытовом смысле.
Вероятно, изначальная проблема в том, что mb_strpos был вызван без указания кодировки, а внутренняя mb-кодировка ни разу не utf/

Более удобная альтернатива - продаться регуляркам:

Код

    foreach($string as $initial) {
     preg_match('/(\S).*\s+(\S)/u',$initial,$m);
     printf('%s -- %s.%s.<br/>',$initial,$m[1],$m[2]);
    }



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
WebDisaster
Дата 13.1.2016, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 406
Регистрация: 22.6.2007

Репутация: нет
Всего: 19



Цитата(ksnk @  13.1.2016,  12:23 Найти цитируемый пост)
Вероятно, изначальная проблема в том, что mb_strpos был вызван без указания кодировки

Точно, дело в этом ) Следующий вариант работает уже правильно

Код

    $string[] = 'Андрей Васильевич';
    $string[] = 'Тамара Николаевна';
    $string[] = 'Татьяна Александровна';
    foreach($string as $initial) {
        $initial    = trim($initial);                        // Удаляем концевые пробелы
        $initial    = preg_replace('/\s+/', ' ', $initial);        // Разные варианты разделения слов заменяем на один пробел
        $pos        = mb_strpos($initial, ' ', 0, 'utf-8');        // Ищем позицию пробела в строке "имя отчество"
        echo        $pos . ' - ';                        // Отладочная информация - позиция пробела, которую "нашла" функция mb_strpos()
        $pos        = $pos + 1;                        // Находим позицию первого символа после пробела
        echo        $initial . ' - ';                        // Имя Отчество - 
        $initial_1    = mb_substr($initial, 0, 1, 'utf-8');        // Читаем первый символ в строке
        $initial_1    = mb_strtoupper($initial_1, 'utf-8');        // Переводим в верхний регистр            
        echo    $initial_1 . '.';                        // Выводим с точкой в конце
        $initial_2    = mb_substr($initial, $pos, 1, 'utf-8');    // Читаем первый символ после пробела
        $initial_2    = mb_strtoupper($initial_2, 'utf-8');        // Переводим в верхний регистр    
        echo        $initial_2 . '.<br />';                    // Выводим с точкой в конце
    }

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1359 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.