php strpos utf 8 кириллица
strpos
(PHP 4, PHP 5, PHP 7, PHP 8)
strpos — Возвращает позицию первого вхождения подстроки
Описание
Список параметров
Строка, в которой производится поиск.
Если этот параметр указан, то поиск будет начат с указанного количества символов с начала строки. Если задано отрицательное значение, отсчёт позиции начала поиска будет произведён с конца строки.
Возвращаемые значения
Возвращает позицию, в которой находится искомая строка, относительно начала строки haystack (независимо от смещения (offset)). Также обратите внимание на то, что позиция строки отсчитывается от 0, а не от 1.
Список изменений
Примеры
Пример #1 Использование ===
Пример #3 Использование смещения
Примечания
Замечание: Эта функция безопасна для обработки данных в двоичной форме.
Смотрите также
User Contributed Notes 38 notes
As strpos may return either FALSE (substring absent) or 0 (substring at start of string), strict versus loose equivalency operators must be used very carefully.
To know that a substring is absent, you must use:
To know that a substring is present (in any position including 0), you can use either of:
To know that a substring is at the start of the string, you must use:
To know that a substring is in any position other than the start, you can use any of:
This is a function I wrote to find all occurrences of a string, using strpos recursively.
It is interesting to be aware of the behavior when the treatment of strings with characters using different encodings.
# Now, encoding the string «Fábio» to utf8, we get some «unexpected» outputs. Every letter that is no in regular ASCII table, will use 4 positions(bytes). The starting point remains like before.
# We cant find the characted, because the haystack string is now encoded.
var_dump ( strpos ( utf8_encode ( «Fábio» ), ‘á’ ));
#bool(false)
# To get the expected result, we need to encode the needle too
var_dump ( strpos ( utf8_encode ( «Fábio» ), utf8_encode ( ‘á’ )));
#int(1)
# And, like said before, «á» occupies 4 positions(bytes)
var_dump ( strpos ( utf8_encode ( «Fábio» ), ‘b’ ));
#int(5)
I lost an hour before I noticed that strpos only returns FALSE as a boolean, never TRUE.. This means that
is a different beast then:
since the latter will never be true. After I found out, The warning in the documentation made a lot more sense.
Warning:
this is not unicode safe
strpos($word,’?’) in e?ez-> 1
strpos($word,’?’) in è?ent-> 2
when you want to know how much of substring occurrences, you’ll use «substr_count».
But, retrieve their positions, will be harder.
So, you can do it by starting with the last occurrence :
Docs are missing that WARNING is issued if needle is » (empty string).
In case of empty haystack it just return false:
Warning: strpos(): Empty needle in /in/lADCh on line 3
bool(false)
Warning: strpos(): Empty needle in /in/lADCh on line 7
bool(false)
Note also that warning text may differ depending on php version, see https://3v4l.org/lADCh
Parse strings between two others in to array.
Can be helpfull to custom parsing 🙂
My version of strpos with needles as an array. Also allows for a string, or an array inside an array.
add quotes to the needle
If you would like to find all occurences of a needle inside a haystack you could use this function strposall($haystack,$needle);. It will return an array with all the strpos’s.
The most straightforward way to prevent this function from returning 0 is:
Note this code example below in PHP 7.3
= «17,25» ;
This just gave me some headache since the value I am checking against comes from the database as an integer.
When a value can be of «unknow» type, I find this conversion trick usefull and more readable than a formal casting (for php7.3+):
Find position of nth occurrence of a string:
This function raises a warning if the offset is not between 0 and the length of string:
Warning: strpos(): Offset not contained in string in %s on line %d
To prevent others from staring at the text, note that the wording of the ‘Return Values’ section is ambiguous.
strpos($myString, ‘b’, 40) returns 43, great.
And now the text: «Returns the position of where the needle exists relative to the beginning of the haystack string (independent of offset).»
So it doesn’t really matter what offset I specify; I’ll get the REAL position of the first occurrence in return, which is 3?
«independent of offset» means, you will get the REAL positions, thus, not relative to your starting point (offset).
Substract your offset from strpos()’s answer, then you have the position relative to YOUR offset.
A function I made to find the first occurrence of a particular needle not enclosed in quotes(single or double). Works for simple nesting (no backslashed nesting allowed).
This might be useful.
if you want to get the position of a substring relative to a substring of your string, BUT in REVERSE way:
Проблема с кириллицей в php
Проект разрабатывается в кодировке utf-8. Столкнулся с проблемой обработки строк с символами кириллицы. Код
Т.е. для кириллицы функция не работает.
Что необходимо сделать, чтобы на выходе вместо «Доп�» получить «Дополни»?
4 ответа 4
Если коротко, то для мультибайтовых кодировок используют mb_substr()
Если сайт разрабатывается, как вы пишите, в UTF-8, значит надо разрабатывать UTF-8. Чтобы все мультибайтовые функции работали по умолчанию с разрабатываемой кодировкой, ее надо задать в самом начале (и желательно проверить, задалась или нет):
Если все ок, можете юзать все mb_ без прописки кодировки.
Забыл написать, почему это важно, ну, если вы разрабатываете. Потому что при использовании имени функции в качестве callback прописывать кодировку будет некуда.
mb_substr() вместо substr()
Чтобы в PHP работать с кириллическими строками посимвольно(включая извлечение подстроки и др.) нужно использовать специальные функции: http://php.net/manual/ru/ref.mbstring.php.
Всё из-за того, что на латинице 1 символ = 1 бит, поэтому:
Но кирилические символы занимают 2 бита, поэтому:
При этом можно это учитывать и работать в таком ключе:
Или разбить строку через str_split, указав split_length = 2:
Но так лучше не делать, потому что таким образом нельзя будет работать теперь с латиницей и остальными символами:
Кстати, чтобы нормально разделить сроку с русскими символами на массив символов, то лучше всего это делать так:
Определение кодировки текста в PHP — обзор существующих решений плюс еще один велосипед
Столкнулся с задачей — автоопределение кодировки страницы/текста/чего угодно. Задача не нова, и велосипедов понапридумано уже много. В статье небольшой обзор найденного в сети — плюс предложение своего, как мне кажется, достойного решения.
Если кратко — он не работает.
Давайте смотреть:
Как видим, на выходе — полная каша. Что мы делаем, когда непонятно почему так себя ведет функция? Правильно, гуглим. Нашел замечательный ответ.
Чтобы окончательно развеять все надежды на использование mb_detect_encoding(), надо залезть в исходники расширения mbstring. Итак, закатали рукава, поехали:
Постить полный текст метода не буду, чтобы не засорять статью лишними исходниками. Кому это интересно посмотрят сами. Нас истересует строка под номером 593, где собственно и происходит проверка того, подходит ли символ под кодировку:
Вот основные фильтры для однобайтовой кириллицы:
Windows-1251 (оригинальные комментарии сохранены)
ISO-8859-5 (тут вообще все весело)
Как видим, ISO-8859-5 всегда возвращает TRUE (чтобы вернуть FALSE, нужно выставить filter->flag = 1).
Когда посмотрели фильтры, все встало на свои места. CP1251 от KOI8-R не отличить никак. ISO-8859-5 вообще если есть в списке кодировок — будет всегда детектиться как верная.
В общем, fail. Оно и понятно — только по кодам символов нельзя в общем случае узнать кодировку, так как эти коды пересекаются в разных кодировках.
2. Что выдает гугл
А гугл выдает всякие убожества. Даже не буду постить сюда исходники, сами посмотрите, если захотите (уберите пробел после http://, не знаю я как показать текст не ссылкой):
http:// deer.org.ua/2009/10/06/1/
http:// php.su/forum/topic.php?forum=1&topic=1346
3. Поиск по хабру
2) на мой взгляд, очень интересное решение: habrahabr.ru/blogs/php/27378/#comment_1399654
Минусы и плюсы в комменте по ссылке. Лично я считаю, что только для детекта кодировки это решение избыточно — слишком мощно получается. Определение кодировки в нем — как побочный эффект ).
4. Собственно, мое решение
Идея возникла во время просмотра второй ссылки из прошлого раздела. Идея следующая: берем большой русский текст, замеряем частоты разных букв, по этим частотам детектим кодировку. Забегая вперед, сразу скажу — будут проблемы с большими и маленькими буквами. Поэтому выкладываю примеры частот букв (назовем это — «спектр») как с учетом регистра, так и без (во втором случае к маленькой букве добавлял еще большую с такой же частотой, а большие все удалял). В этих «спектрах» вырезаны все буквы, имеющие частоты меньше 0,001 и пробел. Вот, что у меня получилось после обработки «Войны и Мира»:
Спектры в разных кодировках (ключи массива — коды соответствующих символов в соответствующей кодировке):
Далее. Берем текст неизвестной кодировки, для каждой проверяемой кодировки находим частоту текущего символа и прибавляем к «рейтингу» этой кодировки. Кодировка с бОльшим рейтингом и есть, скорее всего, кодировка текста.
Результаты
У-упс! Полная каша. А потому что большие буквы в CP1251 обычно соответствуют маленьким в KOI8-R. А маленькие буквы используются в свою очередь намного чаще, чем большие. Вот и определяем строку капсом в CP1251 как KOI8-R.
Пробуем делать без учета регистра («спектры» case insensitive)
Как видим, верная кодировка стабильно лидирует и с регистрозависимыми «спектрами» (если строка содержит небольшое количество заглавных букв), и с регистронезависимыми. Во втором случае, с регистронезависимыми, лидирует не так уверенно, конечно, но вполне стабильно даже на маленьких строках. Можно поиграться еще с весами букв — сделать их нелинейными относительно частоты, например.
5. Заключение
В топике не расмотрена работа с UTF-8 — тут никакий принципиальной разницы нету, разве что получение кодов символов и разбиение строки на символы будет несколько длиннее/сложнее.
Эти идеи можно распространить не только на кириллические кодировки, конечно — вопрос только в «спектрах» соответствующих языков/кодировок.
P.S. Если будет очень нужно/интересно — потом выложу второй частью полностью работающую библиотеку на GitHub. Хотя я считаю, что данных в посте вполне достаточно для быстрого написания такой библиотеки и самому под свои нужды — «спектр» для русского языка выложен, его можно без труда перенести на все нужные кодировки.
UPDATED
В комментариях проскочила замечательная функция, ссылку на которую я опубликовал под графом «убожество». Может быть погорячился со словами, но уж как опубликовал, так опубликовал — редактировать такие вещи не привык. Чтобы не быть голословным, давайте разберемся, работает ли она на 100%, как об этом говорит предполагаемый автор.
1) будут ли ошибки при «нормальной» работе этой функции? Предположим, что контент у нас на 100% валидный.
ответ: да, будут.
2) определит ли она что-нибудь кроме UTF-8 и не-UTF-8?
ответ: нет, не определит.