Ctype punct: примеры (PHP)
ctype_punct(mixed $text): boolФункция ctype_punct в PHP
Функция ctype_punct входит в семейство функций расширения Ctype, предназначенных для проверки типов символов. Она проверяет, состоит ли переданная строка только из знаков пунктуации.
Эта функция применяется для валидации строковых данных, когда требуется убедиться, что все символы строки являются печатными знаками пунктуации, а не буквами, цифрами или пробелами. Типичные сценарии использования включают проверку формата вводимых данных, паролей или специальных кодов.
Функция принимает один обязательный аргумент:
text (mixed) - Проверяемая строка. Начиная с PHP 8.1.0, передача нестрокового аргумента является устаревшей. Ранее, если передавалось целое число (int), оно трактовалось как ASCII-код символа.
Возвращаемое значение: bool - true, если каждый символ в строке text является печатным знаком пунктуации, и false в противном случае. Пустая строка вернет false.
К знакам пунктуации, которые проверяет функция, относятся символы, не являющиеся управляющими, буквами, цифрами или пробелами. Например: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
Примеры использования ctype_punct
Проверка строки, состоящей только из знаков пунктуации:
$str1 = "!@#$";
var_dump(ctype_punct($str1));bool(true)
Проверка строки, содержащей буквы:
$str2 = "Hello!";
var_dump(ctype_punct($str2));bool(false)
Проверка строки, содержащей цифры:
$str3 = "123?.";
var_dump(ctype_punct($str3));bool(false)
Проверка пустой строки:
$str4 = "";
var_dump(ctype_punct($str4));bool(false)
Проверка строки с пробелом:
$str5 = "! ";
var_dump(ctype_punct($str5));bool(false)
Похожие функции в PHP
Для проверки типов символов в строке можно использовать другие функции семейства Ctype, а также регулярные выражения.
- ctype_alnum() - проверяет буквенно-цифровые символы.
- ctype_alpha() - проверяет буквенные символы.
- ctype_digit() - проверяет цифровые символы.
- ctype_graph() - проверяет все печатные символы, кроме пробела. Эта функция близка к
ctype_punct, но включает также буквы и цифры. - ctype_print() - проверяет печатные символы, включая пробел.
Функция preg_match() предоставляет более гибкую проверку с помощью шаблонов PCRE.
$str = "!@#$";
$result = (preg_match('/^[\p{P}\p{S}]+$/u', $str) === 1);
var_dump($result);bool(true)
Использование регулярных выражений предпочтительнее при работе с многобайтовыми кодировками (UTF-8) или когда требуется сложная логика проверки. Функции Ctype работают только с однобайтовыми символами (ASCII) и обычно быстрее.
Типичные ошибки использования
До PHP 8.1 функция могла принимать целые числа, трактуя их как ASCII-коды. Теперь это вызывает предупреждение.
// До PHP 8.1
var_dump(ctype_punct(33)); // ASCII 33 = '!'
// Начиная с PHP 8.1
var_dump(ctype_punct(33));// PHP < 8.1: bool(true) // PHP >= 8.1: Deprecated: ctype_punct(): Argument of type int will be interpreted as string in the future
Функция проверяет только ASCII-знаки пунктуации. Символы пунктуации из других кодировок (например, кавычки-ёлочки «») не распознаются.
$str = "«Привет»";
var_dump(ctype_punct($str));bool(false)
Пустая строка возвращает false, что может быть неочевидно.
var_dump(ctype_punct(""));bool(false)
Изменения в последних версиях PHP
В PHP 8.1.0 была изменена обработка нестроковых аргументов. Передача аргумента типа, отличного от string (int, float, null, bool, array, object и т.д.), теперь вызывает уведомление об устаревании (E_DEPRECATED). Функция продолжает работать, интерпретируя целые числа как ASCII-коды, но в будущих версиях ожидается, что она будет принимать только строки (string).
В версиях PHP до 8.1 нестроковые аргументы преобразовывались в целые числа и трактовались как код ASCII. Например, ctype_punct(46) проверяло, является ли символ с кодом 46 (точка '.') знаком пунктуации, и возвращало true.
В PHP 8 и более ранних версиях существенных изменений в поведении функции не было.
Расширенные примеры использования
Функция может помочь в проверке, содержит ли пароль хотя бы один специальный символ, но не состоит исключительно из них.
function validatePassword($pass) {
if (strlen($pass) < 8) {
return "Пароль слишком короткий";
}
if (ctype_alnum($pass)) {
return "Пароль должен содержать хотя бы один специальный символ";
}
if (ctype_punct($pass)) {
return "Пароль не может состоять только из специальных символов";
}
return "Пароль валиден";
}
echo validatePassword("Secure123") . "\n";
echo validatePassword("!@#$") . "\n";
echo validatePassword("Secur3!") . "\n";Пароль должен содержать хотя бы один специальный символ Пароль не может состоять только из специальных символов Пароль валиден
Пример поиска подстрок, которые полностью состоят из пунктуации, в более длинном тексте.
$text = "Привет! Как дела? Отлично... А у тебя? ;)";
$words = preg_split('/\s+/', $text);
$punctWords = [];
foreach ($words as $word) {
// Удаляем возможные прилегающие буквенно-цифровые символы для проверки
$cleanWord = preg_replace('/[\w\\s]/u', '', $word);
if ($cleanWord !== '' && ctype_punct($cleanWord)) {
$punctWords[] = $word;
}
}
print_r($punctWords);Array
(
[0] => !
[1] => ?
[2] => ...
[3] => ?
[4] => ;)
)Поскольку функция работает только с ASCII, строку в UTF-8 можно предварительно обработать.
function containsOnlyAsciiPunct($str) {
// Преобразуем строку в ASCII, заменяя не-ASCII символы
$asciiStr = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str);
// Проверяем результат
return ctype_punct($asciiStr);
}
$test1 = "!@#$";
$test2 = "¡Hola!"; // Испанский восклицательный знак
var_dump(containsOnlyAsciiPunct($test1));
var_dump(containsOnlyAsciiPunct($test2));bool(true) bool(false)
Создание капчи или тестовых данных.
function generatePunctString($length) {
$punctChars = '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~';
$result = '';
$max = strlen($punctChars) - 1;
for ($i = 0; $i < $length; $i++) {
$result .= $punctChars[random_int(0, $max)];
}
return $result;
}
$randomPunct = generatePunctString(5);
echo "Сгенерировано: " . $randomPunct . "\n";
echo "Проверка ctype_punct: " . (ctype_punct($randomPunct) ? 'true' : 'false');Сгенерировано: ;{*^@
Проверка ctype_punct: trueАналоги функции в других языках
В Python для похожих проверок используют модуль string или методы строк.
import string
s = "!@#$"
result = all(c in string.punctuation for c in s)
print(result) # True
# С пустой строкой
print(all(c in string.punctuation for c in "")) # True (особенность all)True True
В JavaScript нет прямой встроенной функции. Обычно применяют регулярные выражения.
let str = "!@#$";
let regex = /^[!-\/:-@\[-\`\{-~]+$/;
console.log(regex.test(str)); // true
console.log(regex.test("a!")); // falsetrue false
В MySQL прямого аналога нет. Можно использовать оператор REGEXP.
SELECT '!@#$' REGEXP '^[[:punct:]]+$' AS is_punct;is_punct: 1
Основное отличие от PHP в том, что аналоги в других языках часто требуют явного использования регулярных выражений или комбинаций функций, тогда как ctype_punct является специализированной и оптимизированной функцией для ASCII.