Как найти текстовое значение в строке

Часто нам нужно найти символ в строке python. Для решения этой задачи разработчики используют метод find(). Он помогает найти индекс первого совпадения подстроки в строке. Если символ или подстрока не найдены, find возвращает -1.

Синтаксис

string.find(substring,start,end)

Метод find принимает три параметра:

  • substring (символ/подстрока) — подстрока, которую нужно найти в данной строке.
  • start (необязательный) — первый индекс, с которого нужно начинать поиск. По умолчанию значение равно 0.
  • end (необязательный) — индекс, на котором нужно закончить поиск. По умолчанию равно длине строки.

Параметры, которые передаются в метод, — это подстрока, которую требуются найти, индекс начала и конца поиска. Значение по умолчанию для начала поиска — 0, а для конца — длина строки.

В этом примере используем метод со значениями по умолчанию.

Метод find() будет искать символ и вернет положение первого совпадения. Даже если символ встречается несколько раз, то метод вернет только положение первого совпадения.


>>> string = "Добро пожаловать!"
>>> print("Индекс первой буквы 'о':", string.find("о"))
Индекс первой буквы 'о': 1

Поиск не с начала строки с аргументом start

Можно искать подстроку, указав также начальное положение поиска.

В этом примере обозначим стартовое положение значением 8 и метод начнет искать с символа с индексом 8. Последним положением будет длина строки — таким образом метод выполнит поиска с индекса 8 до окончания строки.


>>> string = "Специалисты назвали плюсы и минусы Python"
>>> print("Индекс подстроки 'али' без учета первых 8 символов:", string.find("али", 8))
Индекс подстроки 'али' без учета первых 8 символов: 16

Поиск символа в подстроке со start и end

С помощью обоих аргументов (start и end) можно ограничить поиск и не проводить его по всей строке. Найдем индексы слова «пожаловать» и повторим поиск по букве «о».


>>> string = "Добро пожаловать!"
>>> start = string.find("п")
>>> end = string.find("ь") + 1
>>> print("Индекс первой буквы 'о' в подстроке:", string.find("о", start, end))
Индекс первой буквы 'о' в подстроке: 7

Проверка есть ли символ в строке

Мы знаем, что метод find() позволяет найти индекс первого совпадения подстроки. Он возвращает -1 в том случае, если подстрока не была найдена.


>>> string = "Добро пожаловать!"
>>> print("Есть буква 'г'?", string.find("г") != -1)
Есть буква 'г'? False
>>> print("Есть буква 'т'?", string.find("т") != -1)
Есть буква 'т'? True

Поиск последнего вхождения символа в строку

Функция rfind() напоминает find(), а единое отличие в том, что она возвращает максимальный индекс. В обоих случаях же вернется -1, если подстрока не была найдена.

В следующем примере есть строка «Добро пожаловать!». Попробуем найти в ней символ «о» с помощью методов find() и rfind().


>>> string = "Добро пожаловать"
>>> print("Поиск 'о' методом find:", string.find("о"))
Поиск 'о' методом find: 1
>>> print("Поиск 'о' методом rfind:", string.rfind("о"))
Поиск 'о' методом rfind: 11

Вывод показывает, что find() возвращает индекс первого совпадения подстроки, а rfind() — последнего совпадения.

Второй способ поиска — index()

Метод index() помогает найти положение данной подстроки по аналогии с find(). Единственное отличие в том, что index() бросит исключение в том случае, если подстрока не будет найдена, а find() просто вернет -1.

Вот рабочий пример, показывающий разницу в поведении index() и find():


>>> string = "Добро пожаловать"
>>> print("Поиск 'о' методом find:", string.find("о"))
Поиск 'о' методом find: 1
>>> print("Поиск 'о' методом index:", string.index("о"))
Поиск 'о' методом index: 1

В обоих случаях возвращается одна и та же позиция. А теперь попробуем с подстрокой, которой нет в строке:


>>> string = "Добро пожаловать"
>>> print("Поиск 'г' методом find:", string.find("г"))
Поиск 'г' методом find: 1
>>> print("Поиск 'г' методом index:", string.index("г"))
Traceback (most recent call last):
File "pyshell#21", line 1, in module
print("Поиск 'г' методом index:", string.index("г"))
ValueError: substring not found

В этом примере мы пытались найти подстроку «г». Ее там нет, поэтому find() возвращает -1, а index() бросает исключение.

Поиск всех вхождений символа в строку

Чтобы найти общее количество совпадений подстроки в строке можно использовать ту же функцию find(). Пройдемся циклом while по строке и будем задействовать параметр start из метода find().

Изначально переменная start будет равна -1, что бы прибавлять 1 у каждому новому поиску и начать с 0. Внутри цикла проверяем, присутствует ли подстрока в строке с помощью метода find.

Если вернувшееся значение не равно -1, то обновляем значением count.

Вот рабочий пример:


my_string = "Добро пожаловать"
start = -1
count = 0

while True:
start = my_string.find("о", start+1)
if start == -1:
break
count += 1

print("Количество вхождений символа в строку: ", count )

Количество вхождений символа в строку:  4

Выводы

  • Метод find() помогает найти индекс первого совпадения подстроки в данной строке. Возвращает -1, если подстрока не была найдена.
  • В метод передаются три параметра: подстрока, которую нужно найти, start со значением по умолчанию равным 0 и end со значением по умолчанию равным длине строки.
  • Можно искать подстроку в данной строке, задав начальное положение, с которого следует начинать поиск.
  • С помощью параметров start и end можно ограничить зону поиска, чтобы не выполнять его по всей строке.
  • Функция rfind() повторяет возможности find(), но возвращает максимальный индекс (то есть, место последнего совпадения). В обоих случаях возвращается -1, если подстрока не была найдена.
  • index() — еще одна функция, которая возвращает положение подстроки. Отличие лишь в том, что index() бросает исключение, если подстрока не была найдена, а find() возвращает -1.
  • find() можно использовать в том числе и для поиска общего числа совпадений подстроки.

ПОИСК, ПОИСКБ (функции ПОИСК, ПОИСКБ)

Excel для Microsoft 365 Excel для Microsoft 365 для Mac Excel для Интернета Excel 2019 Excel 2019 для Mac Excel 2016 Excel 2016 для Mac Excel 2013 Excel 2010 Excel 2007 Excel для Mac 2011 Excel Starter 2010 Еще…Меньше

В этой статье описаны синтаксис формулы и использование функций ПОИСК и ПОИСКБ в Microsoft Excel.

Описание

Функции ПОИСК И ПОИСКБ находят одну текстовую строку в другой и возвращают начальную позицию первой текстовой строки (считая от первого символа второй текстовой строки). Например, чтобы найти позицию буквы “n” в слове “printer”, можно использовать следующую функцию:

=ПОИСК(“н”;”принтер”)

Эта функция возвращает 4, так как “н” является четвертым символом в слове “принтер”.

Можно также находить слова в других словах. Например, функция

=ПОИСК(“base”;”database”)

возвращает 5, так как слово “base” начинается с пятого символа слова “database”. Можно использовать функции ПОИСК и ПОИСКБ для определения положения символа или текстовой строки в другой текстовой строке, а затем вернуть текст с помощью функций ПСТР и ПСТРБ или заменить его с помощью функций ЗАМЕНИТЬ и ЗАМЕНИТЬБ. Эти функции показаны в примере 1 данной статьи.

Важно: 

  • Эти функции могут быть доступны не на всех языках.

  • Функция ПОИСКБ отсчитывает по два байта на каждый символ, только если языком по умолчанию является язык с поддержкой БДЦС. В противном случае функция ПОИСКБ работает так же, как функция ПОИСК, и отсчитывает по одному байту на каждый символ.

К языкам, поддерживающим БДЦС, относятся японский, китайский (упрощенное письмо), китайский (традиционное письмо) и корейский.

Синтаксис

ПОИСК(искомый_текст;просматриваемый_текст;[начальная_позиция])

ПОИСКБ(искомый_текст;просматриваемый_текст;[начальная_позиция])

Аргументы функций ПОИСК и ПОИСКБ описаны ниже.

  • Искомый_текст    Обязательный. Текст, который требуется найти.

  • Просматриваемый_текст    Обязательный. Текст, в котором нужно найти значение аргумента искомый_текст.

  • Начальная_позиция    Необязательный. Номер знака в аргументе просматриваемый_текст, с которого следует начать поиск.

Замечание

  • Функции ПОИСК и ПОИСКБ не учитывают регистр. Если требуется учитывать регистр, используйте функции НАЙТИ и НАЙТИБ.

  • В аргументе искомый_текст можно использовать подстановочные знаки: вопросительный знак (?) и звездочку (*). Вопросительный знак соответствует любому знаку, звездочка — любой последовательности знаков. Если требуется найти вопросительный знак или звездочку, введите перед ним тильду (~).

  • Если значение find_text не найдено, #VALUE! возвращается значение ошибки.

  • Если аргумент начальная_позиция опущен, то он полагается равным 1.

  • Если start_num больше нуля или больше, чем длина аргумента within_text, #VALUE! возвращается значение ошибки.

  • Аргумент начальная_позиция можно использовать, чтобы пропустить определенное количество знаков. Допустим, что функцию ПОИСК нужно использовать для работы с текстовой строкой “МДС0093.МужскаяОдежда”. Чтобы найти первое вхождение “М” в описательной части текстовой строки, задайте для аргумента начальная_позиция значение 8, чтобы поиск не выполнялся в той части текста, которая является серийным номером (в данном случае — “МДС0093”). Функция ПОИСК начинает поиск с восьмого символа, находит знак, указанный в аргументе искомый_текст, в следующей позиции, и возвращает число 9. Функция ПОИСК всегда возвращает номер знака, считая от начала просматриваемого текста, включая символы, которые пропускаются, если значение аргумента начальная_позиция больше 1.

Примеры

Скопируйте образец данных из следующей таблицы и вставьте их в ячейку A1 нового листа Excel. Чтобы отобразить результаты формул, выделите их и нажмите клавишу F2, а затем — клавишу ВВОД. При необходимости измените ширину столбцов, чтобы видеть все данные.

Данные

Выписки

Доход: маржа

маржа

Здесь “босс”.

Формула

Описание

Результат

=ПОИСК(“и”;A2;6)

Позиция первого знака “и” в строке ячейки A2, начиная с шестого знака.

7

=ПОИСК(A4;A3)

Начальная позиция строки “маржа” (искомая строка в ячейке A4) в строке “Доход: маржа” (ячейка, в которой выполняется поиск — A3).

8

=ЗАМЕНИТЬ(A3;ПОИСК(A4;A3);6;”объем”)

Заменяет слово “маржа” словом “объем”, определяя позицию слова “маржа” в ячейке A3 и заменяя этот знак и последующие пять знаков текстовой строкой “объем.”

Доход: объем

=ПСТР(A3;ПОИСК(” “;A3)+1,4)

Возвращает первые четыре знака, которые следуют за первым пробелом в строке “Доход: маржа” (ячейка A3).

марж

=ПОИСК(“”””;A5)

Позиция первой двойной кавычки (“) в ячейке A5.

5

=ПСТР(A5;ПОИСК(“”””;A5)+1;ПОИСК(“”””;A5;ПОИСК(“”””;A5)+1)-ПОИСК(“”””;A5)-1)

Возвращает из ячейки A5 только текст, заключенный в двойные кавычки.

босс

Нужна дополнительная помощь?

Нужны дополнительные параметры?

Изучите преимущества подписки, просмотрите учебные курсы, узнайте, как защитить свое устройство и т. д.

В сообществах можно задавать вопросы и отвечать на них, отправлять отзывы и консультироваться с экспертами разных профилей.

Теги: javascript, символ, поиск, методы, строка, индекс, проверка, строковые функции, слово, indexof

Для поиска слова, символа или любой другой подстроки в строке в языке программирования JavaScript используют хорошо известный метод indexOf. В результате проверки метод возвращает позицию первого совпадения, если же совпадение по введённому вами символу найдено не будет, будет возвращено -1.

JavaScriptPro_970x90-20219-f847d3.png

Искомое слово или символ указываются первым параметром. Что касается второго параметра, то он необязателен. Зато с его помощью мы можем передать номер (индекс) символа или буквы, с которого надо начинать поиск. Важный момент: метод indexOf() чувствителен к регистру вводимых вами букв, слов и символов.

Синтаксис метода предельно прост:

строка.indexOf(первый параметр указывает, что ищем, [второй параметр определяет, откуда начинаем поиск]);

Приведем примеры поиска слова в строке JavaScript

В примере ниже у нас есть строка ‘Я учусь в OTUS’, причём мы ищем в строке слово ‘учусь’. Метод вернёт нам индекс 2, т. к. именно с этой позиции начинается слово ‘учусь’ в строке. Тут стоит вспомнить, что индексация (подсчёт позиции) начинается с нуля, а не с единицы.

let str = 'Я учусь в OTUS;
console.log(str.indexOf('учусь'));

В результате получим следующий вывод:


В очередном примере в строке ‘Я учу Java и учу JavaScript в OTUS’ давайте найдём слово ‘учу’, но не первое его вхождение в строку, а второе. Следовательно, начнём поиск с 5-й позиции, указав это вторым параметром.

let str = 'Я учу Java и учу JavaScript в OTUS';
console.log(str.indexOf('учу', 5));

Проверка приведёт к возвращению числа 13, т. к. именно с этой позиции начинается второе слово «учу» в нашей строке.

Давайте приведем ещё парочку примеров. В коде ниже, исследуемый нами метод поиска вернёт -1, ведь подстроки ‘Go’ в нашей строке попросту нет:

let str = 'Я учусь в OTUS';
console.log(str.indexOf('Go'));

В принципе, как видите, ничего сложного. Нам вернётся -1 и в случае, если мы будем искать одинаковые слова с разным регистром (OTUS не равно OtuS):

let str = 'Я учусь в OTUS;
console.log(str.indexOf(' OtuS'));

Вернётся -1 и в последнем примере, ведь после позиции, которую мы выбрали вторым параметром для поиска, совпадения найдены не будут:

let str = 'Я учусь в OTUS';
console.log(str.indexOf('учусь', 7));

Проверка приведёт к следующему результату:


Вот и всё, что можно сказать про простейший поиск слов и символов в строке JavaScript. Напоследок стоит упомянуть метод lastIndexOf(), тоже осуществляющий поиск символа, слова или любой подстроки в строке. Разница заключается лишь в том, что этот метод начинает искать с конца строки, а не с начала — в остальном он работает аналогично.

Больше операций по поиску в строке JavaScript, включая дополнительные операции по работе с подстрокой, вы найдёте здесь.

Интересует профессиональный курс по JavaScript-разработке? Переходите по ссылке ниже:

JavaScriptPro_970x550-20219-412f62.png

(PHP 4, PHP 5, PHP 7, PHP 8)

strposВозвращает позицию первого вхождения подстроки

Описание

strpos(string $haystack, string $needle, int $offset = 0): int|false

Список параметров

haystack

Строка, в которой производится поиск.

needle

До PHP 8.0.0, если параметр needle не является строкой,
он преобразуется в целое число и трактуется как код символа.
Это поведение устарело с PHP 7.3.0, и полагаться на него крайне не рекомендуется.
В зависимости от предполагаемого поведения,
параметр needle должен быть либо явно приведён к строке,
либо должен быть выполнен явный вызов chr().

offset

Если этот параметр указан, то поиск будет начат с указанного количества символов с
начала строки. Если задано отрицательное значение, отсчёт позиции начала поиска
будет произведён с конца строки.

Возвращаемые значения

Возвращает позицию, в которой находится искомая строка, относительно
начала строки haystack (независимо от смещения (offset)).
Также обратите внимание на то, что позиция строки отсчитывается от 0, а не от 1.

Возвращает false, если искомая строка не найдена.

Внимание

Эта функция может возвращать как логическое значение false, так и значение не типа boolean, которое приводится к false. За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.

Список изменений

Версия Описание
8.0.0 Передача целого числа (int) в needle больше не поддерживается.
7.3.0 Передача целого числа (int) в needle объявлена устаревшей.
7.1.0 Добавлена поддержка отрицательных значений offset.

Примеры

Пример #1 Использование ===


<?php
$mystring
= 'abc';
$findme = 'a';
$pos = strpos($mystring, $findme);// Заметьте, что используется ===. Использование == не даст верного
// результата, так как 'a' находится в нулевой позиции.
if ($pos === false) {
echo
"Строка '$findme' не найдена в строке '$mystring'";
} else {
echo
"Строка '$findme' найдена в строке '$mystring'";
echo
" в позиции $pos";
}
?>

Пример #2 Использование !==


<?php
$mystring
= 'abc';
$findme = 'a';
$pos = strpos($mystring, $findme);// Оператор !== также можно использовать. Использование != не даст верного
// результата, так как 'a' находится в нулевой позиции. Выражение (0 != false) приводится
// к false.
if ($pos !== false) {
echo
"Строка '$findme' найдена в строке '$mystring'";
echo
" в позиции $pos";
} else {
echo
"Строка '$findme' не найдена в строке '$mystring'";
}
?>

Пример #3 Использование смещения


<?php
// Можно искать символ, игнорируя символы до определённого смещения
$newstring = 'abcdef abcdef';
$pos = strpos($newstring, 'a', 1); // $pos = 7, не 0
?>

Примечания

Замечание: Эта функция безопасна для обработки данных в двоичной форме.

Смотрите также

  • stripos() – Возвращает позицию первого вхождения подстроки без учёта регистра
  • str_contains() – Определяет, содержит ли строка заданную подстроку
  • str_ends_with() – Проверяет, заканчивается ли строка заданной подстрокой
  • str_starts_with() – Проверяет, начинается ли строка с заданной подстроки
  • strrpos() – Возвращает позицию последнего вхождения подстроки в строке
  • strripos() – Возвращает позицию последнего вхождения подстроки без учёта регистра
  • strstr() – Находит первое вхождение подстроки
  • strpbrk() – Ищет в строке любой символ из заданного набора
  • substr() – Возвращает подстроку
  • preg_match() – Выполняет проверку на соответствие регулярному выражению

Suggested re-write for pink WARNING box

15 years ago


WARNING

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: 

=== FALSE

To know that a substring is present (in any position including 0), you can use either of:

!== FALSE  (recommended)
> -1  (note: or greater than any negative number)

To know that a substring is at the start of the string, you must use: 

=== 0

To know that a substring is in any position other than the start, you can use any of:

> 0  (recommended)
!= 0  (note: but not !== 0 which also equates to FALSE)
!= FALSE  (disrecommended as highly confusing)

Also note that you cannot compare a value of "" to the returned value of strpos. With a loose equivalence operator (== or !=) it will return results which don't distinguish between the substring's presence versus position. With a strict equivalence operator (=== or !==) it will always return false.


martijn at martijnfrazer dot nl

11 years ago


This is a function I wrote to find all occurrences of a string, using strpos recursively.

<?php
function strpos_recursive($haystack, $needle, $offset = 0, &$results = array()) {               
   
$offset = strpos($haystack, $needle, $offset);
    if(
$offset === false) {
        return
$results;           
    } else {
       
$results[] = $offset;
        return
strpos_recursive($haystack, $needle, ($offset + 1), $results);
    }
}
?>

This is how you use it:

<?php
$string
= 'This is some string';
$search = 'a';
$found = strpos_recursive($string, $search);

if(

$found) {
    foreach(
$found as $pos) {
        echo
'Found "'.$search.'" in string "'.$string.'" at position <b>'.$pos.'</b><br />';
    }   
} else {
    echo
'"'.$search.'" not found in "'.$string.'"';
}
?>


fabio at naoimporta dot com

7 years ago


It is interesting to be aware of the behavior when the treatment of strings with characters using different encodings.

<?php
# Works like expected. There is no accent
var_dump(strpos("Fabio", 'b'));
#int(2)

# The "á" letter is occupying two positions

var_dump(strpos("Fábio", 'b')) ;
#int(3)

# 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)


mtroy dot student at gmail dot com

11 years ago


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 :

function strpos_r($haystack, $needle)
{
    if(strlen($needle) > strlen($haystack))
        trigger_error(sprintf("%s: length of argument 2 must be <= argument 1", __FUNCTION__), E_USER_WARNING);

    $seeks = array();
    while($seek = strrpos($haystack, $needle))
    {
        array_push($seeks, $seek);
        $haystack = substr($haystack, 0, $seek);
    }
    return $seeks;
}

it will return an array of all occurrences a the substring in the string

Example :

$test = "this is a test for testing a test function... blah blah";
var_dump(strpos_r($test, "test"));

// output

array(3) {
  [0]=>
  int(29)
  [1]=>
  int(19)
  [2]=>
  int(10)
}

Paul-antoine
Malézieux.


rjeggens at ijskoud dot org

11 years ago


I lost an hour before I noticed that strpos only returns FALSE as a boolean, never TRUE.. This means that

strpos() !== false

is a different beast then:

strpos() === true

since the latter will never be true. After I found out, The warning in the documentation made a lot more sense.


m.m.j.kronenburg

6 years ago


<?php/**
* Find the position of the first occurrence of one or more substrings in a
* string.
*
* This function is simulair to function strpos() except that it allows to
* search for multiple needles at once.
*
* @param string $haystack    The string to search in.
* @param mixed $needles      Array containing needles or string containing
*                            needle.
* @param integer $offset     If specified, search will start this number of
*                            characters counted from the beginning of the
*                            string.
* @param boolean $last       If TRUE then the farthest position from the start
*                            of one of the needles is returned.
*                            If FALSE then the smallest position from start of
*                            one of the needles is returned.
**/
function mstrpos($haystack, $needles, $offset = 0, $last = false)
{
  if(!
is_array($needles)) { $needles = array($needles); }
 
$found = false;
  foreach(
$needles as $needle)
  {
   
$position = strpos($haystack, (string)$needle, $offset);
    if(
$position === false) { continue; }
   
$exp = $last ? ($found === false || $position > $found) :
      (
$found === false || $position < $found);
    if(
$exp) { $found = $position; }
  }
  return
$found;
}
/**
* Find the position of the first (partially) occurrence of a substring in a
* string.
*
* This function is simulair to function strpos() except that it wil return a
* position when the substring is partially located at the end of the string.
*
* @param string $haystack    The string to search in.
* @param mixed $needle       The needle to search for.
* @param integer $offset     If specified, search will start this number of
*                            characters counted from the beginning of the
*                            string.
**/
function pstrpos($haystack, $needle, $offset = 0)
{
 
$position = strpos($haystack, $needle, $offset);
  if(
$position !== false) { return $position; }

    for(

$i = strlen($needle); $i > 0; $i--)
  {
    if(
substr($needle, 0, $i) == substr($haystack, -$i))
    { return
strlen($haystack) - $i; }
  }
  return
false;
}
/**
* Find the position of the first (partially) occurrence of one or more
* substrings in a string.
*
* This function is simulair to function strpos() except that it allows to
* search for multiple needles at once and it wil return a position when one of
* the substrings is partially located at the end of the string.
*
* @param string $haystack    The string to search in.
* @param mixed $needles      Array containing needles or string containing
*                            needle.
* @param integer $offset     If specified, search will start this number of
*                            characters counted from the beginning of the
*                            string.
* @param boolean $last       If TRUE then the farthest position from the start
*                            of one of the needles is returned.
*                            If FALSE then the smallest position from start of
*                            one of the needles is returned.
**/
function mpstrpos($haystack, $needles, $offset = 0, $last = false)
{
  if(!
is_array($needles)) { $needles = array($needles); }
 
$found = false;
  foreach(
$needles as $needle)
  {
   
$position = pstrpos($haystack, (string)$needle, $offset);
    if(
$position === false) { continue; }
   
$exp = $last ? ($found === false || $position > $found) :
      (
$found === false || $position < $found);
    if(
$exp) { $found = $position; }
  }
  return
$found;
}
?>

jexy dot ru at gmail dot com

6 years ago


Docs are missing that WARNING is issued if needle is '' (empty string).

In case of empty haystack it just return false:

For example:

<?php
var_dump
(strpos('foo', ''));var_dump(strpos('', 'foo'));var_dump(strpos('', ''));
?>

will output:

Warning: strpos(): Empty needle in /in/lADCh on line 3
bool(false)

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


greg at spotx dot net

5 years ago


Warning:
this is not unicode safe

strpos($word,'?') in e?ez-> 1
strpos($word,'?') in è?ent-> 2


usulaco at gmail dot com

12 years ago


Parse strings between two others in to array.

<?php

function g($string,$start,$end){

    
preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);

    
$out = array();

     foreach(

$m[1] as $key => $value){

      
$type = explode('::',$value);

       if(
sizeof($type)>1){

          if(!
is_array($out[$type[0]]))

            
$out[$type[0]] = array();

         
$out[$type[0]][] = $type[1];

       } else {

         
$out[] = $value;

       }

     }

  return
$out;

}

print_r(g('Sample text, [/text to extract/] Rest of sample text [/WEB::http://google.com/] bla bla bla. ','[/','/]'));

?>



results:

Array

(

    [0] => text to extract

    [WEB] => Array

        (

            [0] => http://google.com

        )

)

Can be helpfull to custom parsing :)


akarmenia at gmail dot com

12 years ago


My version of strpos with needles as an array. Also allows for a string, or an array inside an array.

<?php
function strpos_array($haystack, $needles) {
    if (
is_array($needles) ) {
        foreach (
$needles as $str) {
            if (
is_array($str) ) {
               
$pos = strpos_array($haystack, $str);
            } else {
               
$pos = strpos($haystack, $str);
            }
            if (
$pos !== FALSE) {
                return
$pos;
            }
        }
    } else {
        return
strpos($haystack, $needles);
    }
}
// Test
echo strpos_array('This is a test', array('test', 'drive')); // Output is 10?>


eef dot vreeland at gmail dot com

6 years ago


To prevent others from staring at the text, note that the wording of the 'Return Values' section is ambiguous.

Let's say you have a string $myString containing 50 'a's except on position 3 and 43, they contain 'b'.
And for this moment, forget that counting starts from 0.

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?

... no ...

"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.


ohcc at 163 dot com

8 years ago


Be careful when the $haystack or $needle parameter is an integer.
If you are not sure of its type, you should  convert it into a string.
<?php
    var_dump
(strpos(12345,1));//false
   
var_dump(strpos(12345,'1'));//0
   
var_dump(strpos('12345',1));//false
   
var_dump(strpos('12345','1'));//0
   
$a = 12345;
   
$b = 1;
   
var_dump(strpos(strval($a),strval($b)));//0
   
var_dump(strpos((string)$a,(string)$b));//0   
?>

ilaymyhat-rem0ve at yahoo dot com

15 years ago


This might be useful.

<?php

class String{
//Look for a $needle in $haystack in any position

   
public static function contains(&$haystack, &$needle, &$offset)

    {

       
$result = strpos($haystack, $needle, $offset);

        return
$result !== FALSE;

    }
//intuitive implementation .. if not found returns -1.

   
public static function strpos(&$haystack, &$needle, &$offset)

    {

       
$result = strpos($haystack, $needle, $offset);

        if (
$result === FALSE )

        {

            return -
1;

        }

        return
$result;

    }

   
}

//String

?>


yasindagli at gmail dot com

13 years ago


This function finds postion of nth occurence of a letter starting from offset.

<?php
function nth_position($str, $letter, $n, $offset = 0){
   
$str_arr = str_split($str);
   
$letter_size = array_count_values(str_split(substr($str, $offset)));
    if( !isset(
$letter_size[$letter])){
       
trigger_error('letter "' . $letter . '" does not exist in ' . $str . ' after ' . $offset . '. position', E_USER_WARNING);
        return
false;
    } else if(
$letter_size[$letter] < $n) {
       
trigger_error('letter "' . $letter . '" does not exist ' . $n .' times in ' . $str . ' after ' . $offset . '. position', E_USER_WARNING);
        return
false;
    }
    for(
$i = $offset, $x = 0, $count = (count($str_arr) - $offset); $i < $count, $x != $n; $i++){
        if(
$str_arr[$i] == $letter){
           
$x++;
        }
    }
    return
$i - 1;
}

echo

nth_position('foobarbaz', 'a', 2); //7
echo nth_position('foobarbaz', 'b', 1, 4); //6
?>


bishop

19 years ago


Code like this:
<?php
if (strpos('this is a test', 'is') !== false) {
    echo
"found it";
}
?>

gets repetitive, is not very self-explanatory, and most people handle it incorrectly anyway. Make your life easier:

<?php
function str_contains($haystack, $needle, $ignoreCase = false) {
    if (
$ignoreCase) {
       
$haystack = strtolower($haystack);
       
$needle   = strtolower($needle);
    }
   
$needlePos = strpos($haystack, $needle);
    return (
$needlePos === false ? false : ($needlePos+1));
}
?>

Then, you may do:
<?php
// simplest use
if (str_contains('this is a test', 'is')) {
    echo
"Found it";
}
// when you need the position, as well whether it's present
$needlePos = str_contains('this is a test', 'is');
if (
$needlePos) {
    echo
'Found it at position ' . ($needlePos-1);
}
// you may also ignore case
$needlePos = str_contains('this is a test', 'IS', true);
if (
$needlePos) {
    echo
'Found it at position ' . ($needlePos-1);
}
?>


Jean

4 years ago


When a value can be of "unknow" type, I find this conversion trick usefull and more readable than a formal casting (for php7.3+):

<?php
$time
= time();
$string = 'This is a test: ' . $time;
echo (
strpos($string, $time) !== false ? 'found' : 'not found');
echo (
strpos($string, "$time") !== false ? 'found' : 'not found');
?>


Anonymous

10 years ago


The most straightforward way to prevent this function from returning 0 is:

  strpos('x'.$haystack, $needle, 1)

The 'x' is simply a garbage character which is only there to move everything 1 position.
The number 1 is there to make sure that this 'x' is ignored in the search.
This way, if $haystack starts with $needle, then the function returns 1 (rather than 0).


marvin_elia at web dot de

5 years ago


Find position of nth occurrence of a string:

    function strpos_occurrence(string $string, string $needle, int $occurrence, int $offset = null) {
        if((0 < $occurrence) && ($length = strlen($needle))) {
            do {
            } while ((false !== $offset = strpos($string, $needle, $offset)) && --$occurrence && ($offset += $length));
            return $offset;
        }
        return false;
    }


digitalpbk [at] gmail.com

13 years ago


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


Achintya

13 years ago


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).

<?php

function strposq($haystack, $needle, $offset = 0){

   
$len = strlen($haystack);

   
$charlen = strlen($needle);

   
$flag1 = false;

   
$flag2 = false;

    for(
$i = $offset; $i < $len; $i++){

        if(
substr($haystack, $i, 1) == "'"){

           
$flag1 = !$flag1 && !$flag2 ? true : false;

        }

        if(
substr($haystack, $i, 1) == '"'){

           
$flag2 = !$flag1 && !$flag2 ? true : false;

        }

        if(
substr($haystack, $i, $charlen) == $needle && !$flag1 && !$flag2){

            return
$i;       

        }

    }

    return
false;

}

echo

strposq("he'llo'character;"'som"e;crap", ";"); //16

?>


spinicrus at gmail dot com

16 years ago


if you want to get the position of a substring relative to a substring of your string, BUT in REVERSE way:

<?phpfunction strpos_reverse_way($string,$charToFind,$relativeChar) {
   
//
   
$relativePos = strpos($string,$relativeChar);
   
$searchPos = $relativePos;
   
$searchChar = '';
   
//
   
while ($searchChar != $charToFind) {
       
$newPos = $searchPos-1;
       
$searchChar = substr($string,$newPos,strlen($charToFind));
       
$searchPos = $newPos;
    }
   
//
   
if (!empty($searchChar)) {
       
//
       
return $searchPos;
        return
TRUE;
    }
    else {
        return
FALSE;
    }
   
//
}?>


lairdshaw at yahoo dot com dot au

8 years ago


<?php
/*
* A strpos variant that accepts an array of $needles - or just a string,
* so that it can be used as a drop-in replacement for the standard strpos,
* and in which case it simply wraps around strpos and stripos so as not
* to reduce performance.
*
* The "m" in "strposm" indicates that it accepts *m*ultiple needles.
*
* Finds the earliest match of *all* needles. Returns the position of this match
* or false if none found, as does the standard strpos. Optionally also returns
* via $match either the matching needle as a string (by default) or the index
* into $needles of the matching needle (if the STRPOSM_MATCH_AS_INDEX flag is
* set).
*
* Case-insensitive searching can be specified via the STRPOSM_CI flag.
* Note that for case-insensitive searches, if the STRPOSM_MATCH_AS_INDEX is
* not set, then $match will be in the haystack's case, not the needle's case,
* unless the STRPOSM_NC flag is also set.
*
* Flags can be combined using the bitwise or operator,
* e.g. $flags = STRPOSM_CI|STRPOSM_NC
*/
define('STRPOSM_CI'            , 1); // CI => "case insensitive".
define('STRPOSM_NC'            , 2); // NC => "needle case".
define('STRPOSM_MATCH_AS_INDEX', 4);
function
strposm($haystack, $needles, $offset = 0, &$match = null, $flags = 0) {
   
// In the special case where $needles is not an array, simply wrap
    // strpos and stripos for performance reasons.
   
if (!is_array($needles)) {
       
$func = $flags & STRPOSM_CI ? 'stripos' : 'strpos';
       
$pos = $func($haystack, $needles, $offset);
        if (
$pos !== false) {
           
$match = (($flags & STRPOSM_MATCH_AS_INDEX)
                      ?
0
                     
: (($flags & STRPOSM_NC)
                         ?
$needles
                        
: substr($haystack, $pos, strlen($needles))
                        )
                      );
            return
$pos;
        } else    goto
strposm_no_match;
    }
// $needles is an array. Proceed appropriately, initially by...
    // ...escaping regular expression meta characters in the needles.
   
$needles_esc = array_map('preg_quote', $needles);
   
// If either of the "needle case" or "match as index" flags are set,
    // then create a sub-match for each escaped needle by enclosing it in
    // parentheses. We use these later to find the index of the matching
    // needle.
   
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
       
$needles_esc = array_map(
            function(
$needle) {return '('.$needle.')';},
           
$needles_esc
       
);
    }
   
// Create the regular expression pattern to search for all needles.
   
$pattern = '('.implode('|', $needles_esc).')';
   
// If the "case insensitive" flag is set, then modify the regular
    // expression with "i", meaning that the match is "caseless".
   
if ($flags & STRPOSM_CI) $pattern .= 'i';
   
// Find the first match, including its offset.
   
if (preg_match($pattern, $haystack, $matches, PREG_OFFSET_CAPTURE, $offset)) {
       
// Pull the first entry, the overall match, out of the matches array.
       
$found = array_shift($matches);
       
// If we need the index of the matching needle, then...
       
if (($flags & STRPOSM_NC) || ($flags & STRPOSM_MATCH_AS_INDEX)) {
           
// ...find the index of the sub-match that is identical
            // to the overall match that we just pulled out.
            // Because sub-matches are in the same order as needles,
            // this is also the index into $needles of the matching
            // needle.
           
$index = array_search($found, $matches);
        }
       
// If the "match as index" flag is set, then return in $match
        // the matching needle's index, otherwise...
       
$match = (($flags & STRPOSM_MATCH_AS_INDEX)
          ?
$index
         
// ...if the "needle case" flag is set, then index into
          // $needles using the previously-determined index to return
          // in $match the matching needle in needle case, otherwise...
         
: (($flags & STRPOSM_NC)
             ?
$needles[$index]
            
// ...by default, return in $match the matching needle in
             // haystack case.
            
: $found[0]
          )
        );
       
// Return the captured offset.
       
return $found[1];
    }
strposm_no_match:
   
// Nothing matched. Set appropriate return values.
   
$match = ($flags & STRPOSM_MATCH_AS_INDEX) ? false : null;
    return
false;
}
?>

qrworld.net

8 years ago


I found a function in this post http://softontherocks.blogspot.com/2014/11/buscar-multiples-textos-en-un-texto-con.html
that implements the search in both ways, case sensitive or case insensitive, depending on an input parameter.

The function is:

function getMultiPos($haystack, $needles, $sensitive=true, $offset=0){
    foreach($needles as $needle) {
        $result[$needle] = ($sensitive) ? strpos($haystack, $needle, $offset) : stripos($haystack, $needle, $offset);
    }
    return $result;
}

It was very useful for me.


Lurvik

9 years ago


Don't know if already posted this, but if I did this is an improvement.

This function will check if a string contains  a needle. It _will_ work with arrays and multidimensional arrays (I've tried with a > 16 dimensional array and had no problem).

<?php
function str_contains($haystack, $needles)
{
   
//If needles is an array
   
if(is_array($needles))
    {
       
//go trough all the elements
       
foreach($needles as $needle)
        {
           
//if the needle is also an array (ie needles is a multidimensional array)
           
if(is_array($needle))
            {
               
//call this function again
               
if(str_contains($haystack, $needle))
                {
                   
//Will break out of loop and function.
                   
return true;
                }

                                return

false;
            }
//when the needle is NOT an array:
                //Check if haystack contains the needle, will ignore case and check for whole words only
           
elseif(preg_match("/b$needleb/i", $haystack) !== 0)
            {
                return
true;
            }
        }
    }
   
//if $needles is not an array...
   
else
    {
        if(
preg_match("/b$needlesb/i", $haystack) !== 0)
        {
            return
true;
        }
    }

    return

false;
}
?>


gambajaja at yahoo dot com

12 years ago


<?php
$my_array
= array ('100,101', '200,201', '300,301');
$check_me_in = array ('100','200','300','400');
foreach (
$check_me_in as $value_cmi){
   
$is_in=FALSE; #asume that $check_me_in isn't in $my_array
   
foreach ($my_array as $value_my){
       
$pos = strpos($value_my, $value_cmi);
        if (
$pos===0)
           
$pos++;
        if (
$pos==TRUE){
           
$is_in=TRUE;
           
$value_my2=$value_my;
            }
    }
    if (
$is_in) echo "ID $value_cmi in $check_me_in I found in value '$value_my2' n";
}
?>

The above example will output
ID 100 in $check_me_in I found in value '100,101'
ID 200 in $check_me_in I found in value '200,201'
ID 300 in $check_me_in I found in value '300,301'

ah dot d at hotmail dot com

13 years ago


A strpos modification to return an array of all the positions of a needle in the haystack

<?php

function strallpos($haystack,$needle,$offset = 0){

   
$result = array();

    for(
$i = $offset; $i<strlen($haystack); $i++){

       
$pos = strpos($haystack,$needle,$i);

        if(
$pos !== FALSE){

           
$offset $pos;

            if(
$offset >= $i){

               
$i = $offset;

               
$result[] = $offset;

            }

        }

    }

    return
$result;

}

?>



example:-

<?php

$haystack
= "ASD is trying to get out of the ASDs cube but the other ASDs told him that his behavior will destroy the ASDs world";
$needle = "ASD";
print_r(strallpos($haystack,$needle));
//getting all the positions starting from a specified position
print_r(strallpos($haystack,$needle,34));

?>


teddanzig at yahoo dot com

14 years ago


routine to return -1 if there is no match for strpos

<?php

//instr function to mimic vb instr fucntion

function InStr($haystack, $needle)

{

   
$pos=strpos($haystack, $needle);

    if (
$pos !== false)

    {

        return
$pos;

    }

    else

    {

        return -
1;

    }

}

?>


Tim

14 years ago


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.

<?php

/**

* strposall

*

* Find all occurrences of a needle in a haystack

*

* @param string $haystack

* @param string $needle

* @return array or false

*/

function strposall($haystack,$needle){
$s=0;

   
$i=0;

   
    while (

is_integer($i)){
$i = strpos($haystack,$needle,$s);

       
        if (

is_integer($i)) {

           
$aStrPos[] = $i;

           
$s = $i+strlen($needle);

        }

    }

    if (isset(
$aStrPos)) {

        return
$aStrPos;

    }

    else {

        return
false;

    }

}

?>


user at nomail dot com

16 years ago


This is a bit more useful when scanning a large string for all occurances between 'tags'.

<?php
function getStrsBetween($s,$s1,$s2=false,$offset=0) {
   
/*====================================================================
    Function to scan a string for items encapsulated within a pair of tags

    getStrsBetween(string, tag1, <tag2>, <offset>

    If no second tag is specified, then match between identical tags

    Returns an array indexed with the encapsulated text, which is in turn
    a sub-array, containing the position of each item.

    Notes:
    strpos($needle,$haystack,$offset)
    substr($string,$start,$length)

    ====================================================================*/

if( $s2 === false ) { $s2 = $s1; }
   
$result = array();
   
$L1 = strlen($s1);
   
$L2 = strlen($s2);

    if(

$L1==0 || $L2==0 ) {
        return
false;
    }

    do {

$pos1 = strpos($s,$s1,$offset);

        if(

$pos1 !== false ) {
           
$pos1 += $L1;$pos2 = strpos($s,$s2,$pos1);

            if(

$pos2 !== false ) {
               
$key_len = $pos2 - $pos1;$this_key = substr($s,$pos1,$key_len);

                if( !

array_key_exists($this_key,$result) ) {
                   
$result[$this_key] = array();
                }
$result[$this_key][] = $pos1;$offset = $pos2 + $L2;
            } else {
               
$pos1 = false;
            }
        }
    } while(
$pos1 !== false );

    return

$result;
}
?>


philip

18 years ago


Many people look for in_string which does not exist in PHP, so, here's the most efficient form of in_string() (that works in both PHP 4/5) that I can think of:

<?php

function in_string($needle, $haystack, $insensitive = false) {

    if (
$insensitive) {

        return
false !== stristr($haystack, $needle);

    } else {

        return
false !== strpos($haystack, $needle);

    }

}

?>

Lhenry

5 years ago


note that strpos( "8 june 1970"  ,  1970 ) returns FALSE..

add quotes to the needle


gjh42 – simonokewode at hotmail dot com

11 years ago


A pair of functions to replace every nth occurrence of a string with another string, starting at any position in the haystack. The first works on a string and the second works on a single-level array of strings, treating it as a single string for replacement purposes (any needles split over two array elements are ignored).

Can be used for formatting dynamically-generated HTML output without touching the original generator: e.g. add a newLine class tag to every third item in a floated list, starting with the fourth item.

<?php
/* String Replace at Intervals   by Glenn Herbert (gjh42)    2010-12-17
*/

//(basic locator by someone else - name unknown)
//strnposr() - Find the position of nth needle in haystack.

function strnposr($haystack, $needle, $occurrence, $pos = 0) {
    return (
$occurrence<2)?strpos($haystack, $needle, $pos):strnposr($haystack,$needle,$occurrence-1,strpos($haystack, $needle, $pos) + 1);
}
//gjh42
//replace every nth occurrence of $needle with $repl, starting from any position
function str_replace_int($needle, $repl, $haystack, $interval, $first=1, $pos=0) {
  if (
$pos >= strlen($haystack) or substr_count($haystack, $needle, $pos) < $first) return $haystack;
 
$firstpos = strnposr($haystack, $needle, $first, $pos);
 
$nl = strlen($needle);
 
$qty = floor(substr_count($haystack, $needle, $firstpos + 1)/$interval);
  do {
//in reverse order
   
$nextpos = strnposr($haystack, $needle, ($qty * $interval) + 1, $firstpos);
   
$qty--;
   
$haystack = substr_replace($haystack, $repl, $nextpos, $nl);
  } while (
$nextpos > $firstpos);
  return
$haystack;
}
 
//$needle = string to find
  //$repl = string to replace needle
  //$haystack = string to do replacing in
  //$interval = number of needles in loop
  //$first=1 = first occurrence of needle to replace (defaults to first)
  //$pos=0 = position in haystack string to start from (defaults to first)

//replace every nth occurrence of $needle with $repl, starting from any position, in a single-level array

function arr_replace_int($needle, $repl, $arr, $interval, $first=1, $pos=0, $glue='|+|') {
  if (!
is_array($arr))  return $arr;
  foreach(
$arr as $key=>$value){
    if (
is_array($arr[$key])) return $arr;
  }
 
$haystack = implode($glue, $arr);
 
$haystack = str_replace_int($needle, $repl, $haystack, $interval, $first, $pos);
 
$tarr = explode($glue, $haystack);
 
$i = 0;
  foreach(
$arr as $key=>$value){
   
$arr[$key] = $tarr[$i];
   
$i++;
  }
  return
$arr;
}
?>
If $arr is not an array, or a multilevel array, it is returned unchanged.


amolocaleb at gmail dot com

4 years ago


Note that strpos() is case sensitive,so when doing a case insensitive search,use stripos() instead..If the latter is not available,subject the string to strlower() first,otherwise you may end up in this situation..
<?php
//say we are matching url routes and calling access control middleware depending on the route$registered_route = '/admin' ;
//now suppose we want to call the authorization middleware before accessing the admin route
if(strpos($path->url(),$registered_route) === 0){
    
$middleware->call('Auth','login');
}
?>
and the auth middleware is as follows
<?php
class Auth{

function

login(){
   if(!
loggedIn()){
       return
redirect("path/to/login.php");
}
return
true;
}
}
//Now suppose:
$user_url = '/admin';
//this will go to the Auth middleware for checks and redirect accordingly

//But:

$user_url = '/Admin';
//this will make the strpos function return false since the 'A' in admin is upper case and user will be taken directly to admin dashboard authentication and authorization notwithstanding
?>
Simple fixes:
<?php
//use stripos() as from php 5
if(stripos($path->url(),$registered_route) === 0){
    
$middleware->call('Auth','login');
}
//for those with php 4
if(stripos(strtolower($path->url()),$registered_route) === 0){
    
$middleware->call('Auth','login');
}
//make sure the $registered_route is also lowercase.Or JUST UPGRADE to PHP 5>

ds at kala-it dot de

3 years ago


Note this code example below in PHP 7.3
<?php
$str
= "17,25";

if(

FALSE !== strpos($str, 25)){
    echo
"25 is inside of str";
} else {
    echo
"25 is NOT inside of str";
}
?>

Will output "25 is NOT inside of str" and will throw out a deprication message, that non string needles will be interpreted as strings in the future.

This just gave me some headache since the value I am checking against comes from the database as an integer.


sunmacet at gmail dot com

2 years ago


To check that a substring is present.

Confusing check if position is not false:

if ( strpos ( $haystack , $needle ) !== FALSE )

Logical check if there is position:

if ( is_int ( strpos ( $haystack , $needle ) ) )


binodluitel at hotmail dot com

9 years ago


This function will return 0 if the string that you are searching matches i.e. needle matches the haystack

{code}
echo strpos('bla', 'bla');
{code}

Output: 0


hu60 dot cn at gmail dot com

3 years ago


A more accurate imitation of the PHP function session_start().

Function my_session_start() does something similar to session_start() that has the default configure, and the session files generated by the two are binary compatible.

The code may help people increase their understanding of the principles of the PHP session.

<?php
error_reporting
(E_ALL);
ini_set('display_errors', true);
ini_set('session.save_path', __DIR__);my_session_start();

echo

'<p>session id: '.my_session_id().'</p>';

echo

'<code><pre>';
var_dump($_SESSION);
echo
'</pre></code>';$now = date('H:i:s');
if (isset(
$_SESSION['last_visit_time'])) {
  echo
'<p>Last Visit Time: '.$_SESSION['last_visit_time'].'</p>';
}
echo
'<p>Current Time: '.$now.'</p>';$_SESSION['last_visit_time'] = $now;

function

my_session_start() {
  global
$phpsessid, $sessfile;

  if (!isset(

$_COOKIE['PHPSESSID']) || empty($_COOKIE['PHPSESSID'])) {
   
$phpsessid = my_base32_encode(my_random_bytes(16));
   
setcookie('PHPSESSID', $phpsessid, ini_get('session.cookie_lifetime'), ini_get('session.cookie_path'), ini_get('session.cookie_domain'), ini_get('session.cookie_secure'), ini_get('session.cookie_httponly'));
  } else {
   
$phpsessid = substr(preg_replace('/[^a-z0-9]/', '', $_COOKIE['PHPSESSID']), 0, 26);
  }
$sessfile = ini_get('session.save_path').'/sess_'.$phpsessid;
  if (
is_file($sessfile)) {
   
$_SESSION = my_unserialize(file_get_contents($sessfile));
  } else {
   
$_SESSION = array();
  }
 
register_shutdown_function('my_session_save');
}

function

my_session_save() {
  global
$sessfile;file_put_contents($sessfile, my_serialize($_SESSION));
}

function

my_session_id() {
  global
$phpsessid;
  return
$phpsessid;
}

function

my_serialize($data) {
 
$text = '';
  foreach (
$data as $k=>$v) {
   
// key cannot contains '|'
   
if (strpos($k, '|') !== false) {
      continue;
    }
   
$text.=$k.'|'.serialize($v)."n";
  }
  return
$text;
}

function

my_unserialize($text) {
 
$data = [];
 
$text = explode("n", $text);
  foreach (
$text as $line) {
   
$pos = strpos($line, '|');
    if (
$pos === false) {
      continue;
    }
   
$data[substr($line, 0, $pos)] = unserialize(substr($line, $pos + 1));
  }
  return
$data;
}

function

my_random_bytes($length) {
  if (
function_exists('random_bytes')) {
      return
random_bytes($length);
  }
 
$randomString = '';
  for (
$i = 0; $i < $length; $i++) {
     
$randomString .= chr(rand(0, 255));
  }
  return
$randomString;
}

function

my_base32_encode($input) {
 
$BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
 
$output = '';
 
$v = 0;
 
$vbits = 0;
  for (
$i = 0, $j = strlen($input); $i < $j; $i++) {
   
$v <<= 8;
   
$v += ord($input[$i]);
   
$vbits += 8;
    while (
$vbits >= 5) {
     
$vbits -= 5;
     
$output .= $BASE32_ALPHABET[$v >> $vbits];
     
$v &= ((1 << $vbits) - 1);
    }
  }
  if (
$vbits > 0) {
   
$v <<= (5 - $vbits);
   
$output .= $BASE32_ALPHABET[$v];
  }
  return
$output;
}


msegit post pl

4 years ago


This might be useful, I often use for parsing file paths etc.
(Some examples inside https://gist.github.com/msegu/bf7160257037ec3e301e7e9c8b05b00a )
<?php
/**
* Function 'strpos_' finds the position of the first or last occurrence of a substring in a string, ignoring number of characters
*
* Function 'strpos_' is similar to 'str[r]pos()', except:
* 1. fourth (last, optional) param tells, what to return if str[r]pos()===false
* 2. third (optional) param $offset tells as of str[r]pos(), BUT if negative (<0) search starts -$offset characters counted from the end AND skips (ignore!, not as 'strpos' and 'strrpos') -$offset-1 characters from the end AND search backwards
*
* @param string $haystack Where to search
* @param string $needle What to find
* @param int $offset (optional) Number of characters to skip from the beginning (if 0, >0) or from the end (if <0) of $haystack
* @param mixed $resultIfFalse (optional) Result, if not found
*    Example:
*    positive $offset - like strpos:
*        strpos_('abcaba','ab',1)==strpos('abcaba','ab',1)==3, strpos('abcaba','ab',4)===false, strpos_('abcaba','ab',4,'Not found')==='Not found'
*    negative $offset - similar to strrpos:
*        strpos_('abcaba','ab',-1)==strpos('abcaba','ab',-1)==3, strrpos('abcaba','ab',-3)==3 BUT strpos_('abcaba','ab',-3)===0 (omits 2 characters from the end, because -2-1=-3, means search in 'abca'!)
*
* @result int $offset Returns offset (or false), or $resultIfFalse
*/
function strpos_($haystack, $needle, $offset = 0, $resultIfFalse = false) {
   
$haystack=((string)$haystack);    // (string) to avoid errors with int, float...
   
$needle=((string)$needle);
    if (
$offset>=0) {
       
$offset=strpos($haystack, $needle, $offset);
        return ((
$offset===false)? $resultIfFalse : $offset);
    } else {
       
$haystack=strrev($haystack);
       
$needle=strrev($needle);
       
$offset=strpos($haystack,$needle,-$offset-1);
        return ((
$offset===false)? $resultIfFalse : strlen($haystack)-$offset-strlen($needle));
    }
}
?>

При работе с базой данных SQL вам может понадобиться найти записи, содержащие определенные строки. В этой статье мы разберем, как искать строки и подстроки в MySQL и SQL Server.

Содержание

  • Использование операторов WHERE и LIKE для поиска подстроки
  • Поиск подстроки в SQL Server с помощью функции CHARINDEX
  • Поиск подстроки в SQL Server с помощью функции PATINDEX
  • MySQL-запрос для поиска подстроки с применением функции SUBSTRING_INDEX()

Я буду использовать таблицу products_data в базе данных products_schema. Выполнение команды SELECT * FROM products_data покажет мне все записи в таблице:

Поскольку я также буду показывать поиск подстроки в SQL Server, у меня есть таблица products_data в базе данных products:

Поиск подстроки при помощи операторов WHERE и LIKE

Оператор WHERE позволяет получить только те записи, которые удовлетворяют определенному условию. А оператор LIKE позволяет найти определенный шаблон в столбце. Эти два оператора можно комбинировать для поиска строки или подстроки.

Например, объединив WHERE с LIKE, я смог получить все товары, в которых есть слово «computer»:

SELECT * FROM products_data
WHERE product_name LIKE '%computer%'

Знаки процента слева и справа от «computer» указывают искать слово «computer» в конце, середине или начале строки.

Если поставить знак процента в начале подстроки, по которой вы ищете, это будет указанием найти такую подстроку, стоящую в конце строки. Например, выполнив следующий запрос, я получил все продукты, которые заканчиваются на «er»:

SELECT * FROM products_data
WHERE product_name LIKE '%er'

А если написать знак процента после искомой подстроки, это будет означать, что нужно найти такую подстроку, стоящую в начале строки. Например, я смог получить продукт, начинающийся на «lap», выполнив следующий запрос:

SELECT * FROM products_data
WHERE product_name LIKE 'lap%'

Этот метод также отлично работает в SQL Server:

Поиск подстроки в SQL Server с помощью функции CHARINDEX

CHARINDEX() — это функция SQL Server для поиска индекса подстроки в строке.

Функция CHARINDEX() принимает 3 аргумента: подстроку, строку и стартовую позицию для поиска. Синтаксис выглядит следующим образом:

CHARINDEX(substring, string, start_position)

Если функция находит совпадение, она возвращает индекс, по которому найдено совпадение, а если совпадение не найдено, возвращает 0. В отличие от многих других языков, отсчет в SQL начинается с единицы.

Пример:

SELECT CHARINDEX('free', 'free is the watchword of freeCodeCamp') position;

Как видите, слово «free» было найдено на позиции 1. Это потому, что на позиции 1 стоит его первая буква — «f»:

Можно задать поиск с конкретной позиции. Например, если указать в качестве позиции 25, SQL Server найдет совпадение, начиная с текста «freeCodeCamp»:

SELECT CHARINDEX('free', 'free is the watchword of freeCodeCamp', 25);

При помощи CHARINDEX можно найти все продукты, в которых есть слово «computer», выполнив этот запрос:

SELECT * FROM products_data WHERE CHARINDEX('computer', product_name, 0) > 0

Этот запрос диктует следующее: «Начиная с индекса 0 и до тех пор, пока их больше 0, ищи все продукты, названия которых содержат слово «computer», в столбце product_name». Вот результат:

Поиск подстроки в SQL Server с помощью функции PATINDEX

PATINDEX означает «pattern index», т. е. «индекс шаблона». Эта функция позволяет искать подстроку с помощью регулярных выражений.

PATINDEX принимает два аргумента: шаблон и строку. Синтаксис выглядит следующим образом:

PATINDEX(pattern, string)

Если PATINDEX находит совпадение, он возвращает позицию этого совпадения. Если совпадение не найдено, возвращается 0. Вот пример:

SELECT PATINDEX('%ava%', 'JavaScript is a Jack of all trades');

Чтобы применить PATINDEX к таблице, я выполнил следующий запрос:

SELECT product_name, PATINDEX('%ann%', product_name) position
FROM products_data

Но он только перечислил все товары и вернул индекс, под которым нашел совпадение:

Как видите, подстрока «ann» нашлась под индексом 3 продукта Scanner. Но скорее всего вы захотите, чтобы выводился только тот товар, в котором было найдено совпадение с шаблоном.

Чтобы обеспечить такое поведение, можно использовать операторы WHERE и LIKE:

SELECT product_name, PATINDEX('%ann%', product_name) position
FROM products_data
WHERE product_name LIKE '%ann%'

Теперь запрос возвращает то, что нужно.

MySQL-запрос для поиска строки с применением функции SUBSTRING_INDEX()

Помимо решений, которые я уже показал, MySQL имеет встроенную функцию SUBSTRING_INDEX(), с помощью которой можно найти часть строки.

Функция SUBSTRING_INDEX() принимает 3 обязательных аргумента: строку, разделитель и число. Числом обозначается количество вхождений разделителя.

Если вы укажете обязательные аргументы, функция SUBSTRING_INDEX() вернет подстроку до n-го разделителя, где n — указанное число вхождений разделителя. Вот пример:

SELECT SUBSTRING_INDEX("Learn on freeCodeCamp with me", "with", 1);

В этом запросе «Learn on freeCodeCamp with me» — это строка, «with» — разделитель, а 1 — количество вхождений разделителя. В этом случае запрос выдаст вам «Learn on freeCodeCamp»:

Количество вхождений разделителя может быть как положительным, так и отрицательным. Если это отрицательное число, то вы получите часть строки после указанного числа разделителей. Вот пример:

SELECT SUBSTRING_INDEX("Learn on freeCodeCamp with me", "with", -1);

От редакции Techrocks: также предлагаем почитать «Индексы и оптимизация MySQL-запросов».

Заключение

Из этой статьи вы узнали, как найти подстроку в строке в SQL, используя MySQL и SQL Server.

CHARINDEX() и PATINDEX() — это функции, с помощью которых можно найти подстроку в строке в SQL Server. Функция PATINDEX() является более мощной, так как позволяет использовать регулярные выражения.

Поскольку в MySQL нет CHARINDEX() и PATINDEX(), в первом примере мы рассмотрели, как найти подстроку в строке с помощью операторов WHERE и LIKE.

Перевод статьи «SQL Where Contains String – Substring Query Example».

Добавить комментарий