Я знаю что нет mb_trim
версия trim
, У меня есть ссылки на дюжину статей о том, как реализовать один, используя preg_replace
,
У меня вопрос, это обычный trim
по умолчанию chars mb безопасно? То есть, есть ли какой-нибудь пример многобайтового символа, который заканчивается однобайтовым пробельным символом?
Это зависит от кодировки, о которой вы говорите. И UTF-16LE, и UTF-32LE имеют тонны символов, заканчивающиеся, например, нулевыми байтами, которые trim
удаляет по умолчанию.
Строка «a» в UTF-16LE состоит из байтов 0x61
0x00
, а также trim
удалит нулевой байт, оставив только 0x61
,
Обратите внимание, что эта проблема идет и в другую сторону, trim
удаляет байты из начала и конца строки, а также до конца. Если ваша строка «a» находится в UTF-16BE, она будет закодирована как 0x00
0x61
— с trim
снова оставив тебя только 0x61
,
Пример:
$utf16le = iconv("ASCII", "UTF-16LE", "a");
$utf16be = iconv("ASCII", "UTF-16BE", "a");
var_dump(
bin2hex($utf16le),
bin2hex(trim($utf16le)),
bin2hex($utf16be),
bin2hex(trim($utf16be))
);
Выход:
string(4) "6100"string(2) "61"string(4) "0061"string(2) "61"
Если вы беспокоитесь только о UTF-8, тогда нет никаких конфликтов. Он совместим с ASCII, и все однобайтовые символы в UTF-8 имеют вид 0xxx xxxx
в то время как все байты многобайтового символа имеют свой самый значимый бит, 1xxx xxxx
, поэтому нет никакой двусмысленности. С UTF-8 trim
использование маски символов по умолчанию безопасно.
Если вы беспокоитесь о других кодировках, то это будет зависеть от того, какие они есть. Если вы попытаетесь использовать многобайтовые символы как часть trim
С символьной маской у вас точно будут проблемы, так как каждый байт будет обрабатываться индивидуально.
Так как символы в маске символов по умолчанию (пробел +\t\n\r\0\x0B
) являются ASCII, это безопасно использовать trim()
с многобутовой струной.
trim(' 漢字は '); // ok
Маска символов с многобайтовыми символами вызовет проблемы.
trim('はは漢字はは', 'は'); // bad