1

Substr compare: примеры (PHP)

Сравнение подстрок в PHP: функция substr_compare
Раздел: Работа со строками
substr_compare(string haystack, string needle, int offset [, int length [, bool case_insensitivity]]): int

Описание функции substr_compare

Функция substr_compare в PHP выполняет бинарно-безопасное сравнение двух строк с заданного смещения. Она используется для сравнения частей строк без необходимости извлечения подстрок в отдельные переменные.

Аргументы функции

main_str (string) – основная строка, в которой происходит сравнение.

str (string) – сравниваемая строка.

offset (int) – начальная позиция в основной строке для начала сравнения. Если значение отрицательное, отсчет идет с конца строки.

length (int, необязательный) – длина сравнения. По умолчанию используется максимальная длина. Если значение отрицательное, то длина считается от конца строки.

case_insensitivity (bool, необязательный) – если равно true, сравнение происходит без учета регистра. По умолчанию false.

Функция возвращает:

  • 0, если подстроки равны.
  • Отрицательное число, если подстрока из main_str (начиная с offset) меньше строки str.
  • Положительное число, если подстрока из main_str больше строки str.
  • false в случае ошибки (например, если offset выходит за пределы строки).

Базовые примеры использования

Простое сравнение
echo substr_compare('abcdef', 'bc', 1, 2);
0
Сравнение с отрицательным смещением
echo substr_compare('abcdef', 'ef', -2, 2);
0
Сравнение без учета регистра
echo substr_compare('AbCdEf', 'cDe', 2, 3, true);
0
Результат при различии строк
echo substr_compare('abcdef', 'abc', 0, 3);
echo '\n';
echo substr_compare('abcdef', 'bcd', 0, 3);
1
-1
Ошибка при недопустимом смещении
var_dump(substr_compare('abc', 'bc', 5));
bool(false)

Похожие функции в PHP

strcmp — бинарно-безопасное сравнение строк. Сравнивает строки целиком, а не их части.

strncmp — бинарно-безопасное сравнение первых n символов строк. Удобно для сравнения префиксов.

strpos — находит позицию первого вхождения подстроки. Используется для проверки наличия подстроки, а не сравнения.

substr — возвращает подстроку. Ее можно сравнить через strcmp, но это менее эффективно, чем прямое сравнение substr_compare.

strcasecmp, strncasecmp — сравнение строк без учета регистра. Аналогично substr_compare с флагом true, но для целых строк или префиксов.

Типичные ошибки

Смещение за пределами строки
var_dump(substr_compare('hello', 'lo', 10));
bool(false)
Использование отрицательной длины, превышающей допустимую
// Строка 'abc', offset=0, length=-10 (эквивалентно length=0)
echo substr_compare('abc', 'abc', 0, -10);
0
Путаница с типами данных
// Передача строки как offset вызовет TypeError в PHP 8
try {
    substr_compare('abc', 'bc', '1');
} catch (TypeError $e) {
    echo $e->getMessage();
}
substr_compare(): Argument #3 ($offset) must be of type int, string given
Неявное приведение некорректных строк
// В PHP 8.0 и выше сравнение с пустой строкой при отрицательном offset может дать неожиданный результат
var_dump(substr_compare('test', '', -1));
int(0) // Начиная с позиции -1 (последний символ) сравнивается пустая строка

Изменения в версиях PHP

PHP 8.0.0: параметр case_insensitivity изменен с типа int на bool. Ранее можно было передавать целое число, теперь только логическое значение.

PHP 7.2.18, 7.3.5: исправлено поведение при использовании отрицательного offset с пустой строкой сравнения.

PHP 5.6.0: параметр length стал необязательным. Раньше его всегда нужно было указывать.

Расширенные примеры

Сравнение с автоматической длиной
Пример php
// length не указан, используется длина второй строки
echo substr_compare('программирование', 'грамм', 3);
0
Поиск подстроки в цикле
Пример php
$haystack = 'abababab';
$needle = 'aba';
$needleLen = strlen($needle);
for ($i = 0; $i <= strlen($haystack) - $needleLen; $i++) {
    if (substr_compare($haystack, $needle, $i, $needleLen) === 0) {
        echo "Найдено в позиции: $i\n";
    }
}
Найдено в позиции: 0
Найдено в позиции: 2
Найдено в позиции: 4
Проверка расширения файла без учета регистра
Пример php
$filename = 'image.PNG';
$extension = '.png';
if (substr_compare($filename, $extension, -strlen($extension), null, true) === 0) {
    echo "Файл имеет расширение $extension\n";
}
Файл имеет расширение .png
Сравнение частей строк с отрицательными параметрами
Пример php
// Сравнение последних 3 символов строки 'testString' со строкой 'ing'
echo substr_compare('testString', 'ing', -3);
0
Комбинирование отрицательных offset и length
Пример php
// Сравнение 2 символов, начиная с 3-го с конца строки 'abcdefgh'
// offset=-3 -> позиция 'f', length=2 -> 'fg'
echo substr_compare('abcdefgh', 'fg', -3, 2);
0

Аналоги в других языках

Substr compare в Python

Прямого аналога нет, но можно использовать срезы строк и операторы сравнения.

main_str = 'abcdef'
str_to_compare = 'bc'
offset = 1
length = 2
result = main_str[offset:offset+length] == str_to_compare
print(result)  # Сравнение на равенство
# Для аналога возвращаемого значения:
if main_str[offset:offset+length] < str_to_compare:
    print(-1)
elif main_str[offset:offset+length] > str_to_compare:
    print(1)
else:
    print(0)
True
0

Substr compare в Javascript

Метод localeCompare() с указанием позиций.

let mainStr = 'abcdef';
let str = 'bc';
let offset = 1;
let length = 2;
let result = mainStr.substring(offset, offset + length).localeCompare(str);
console.log(result);
0

Substr compare в MySQL

Функция SUBSTR() или MID() в сочетании с операторами сравнения.

SELECT CASE
    WHEN SUBSTR('abcdef', 2, 2) = 'bc' THEN 0
    WHEN SUBSTR('abcdef', 2, 2) < 'bc' THEN -1
    ELSE 1
END AS comparison_result;
comparison_result
0

PHP substr_compare function comments

En
Substr compare Binary safe comparison of two strings from an offset, up to length characters