strpos ищет юникод в PHP (и обрабатывает встроенный UTF-8) - PullRequest
2 голосов
/ 23 августа 2010

У меня проблема с простым поиском двухсимвольной строки юникода (иглы) внутри другой строки (стог сена), которая может быть или не быть UTF-8

Отчасти проблема в том, что я не знаю, как указать код для использования в strpos, и я не знаю, должен ли PHP быть скомпилирован с какой-либо специальной поддержкой кода, или мне нужно используйте mb_strpos, который я пытаюсь избежать, поскольку он также может быть недоступен.

есть. например, игла U+56DE U+590D (без пробела)

С preg_match это может быть preg_match("@\x{56DE}\x{590D}@",$haystack) но для этого требуется @u, который может быть недоступен, и я все равно получаю Compilation failed: character value in \x{...} sequence is too large.

Я не хочу использовать preg_match в любом случае, так как он может быть значительно медленнее, чем strpos (есть другие последовательности, которые нужно искать).

Могу ли я преобразовать U+56DE U+590D в его однобайтовую последовательность (возможно, 5-6 символов), а затем найти его с помощью strpos? Я не могу понять, как преобразовать его в байты, если это так.

Как вы в любом случае указываете юникод inline в PHP? Я имею в виду за пределами PRCE?

$blah="\u56DE\u590D"; не работает?

Спасибо за любые идеи!

Ответы [ 2 ]

2 голосов
/ 23 августа 2010

Во-первых, ваш вопрос плохо структурирован.У него есть несколько вопросов по нескольким пунктам.Вы, вероятно, получили бы больше ответов, если бы использовали более четкую структуру: 1) опишите задачу, которую вы пытаетесь выполнить, 2) ограничения / требования, 3) стратегию, которую вы рассмотрели, 4) трудности, которые вы обнаружили с такой стратегией /есть ли лучший.

Тем не менее, я начну к концу:

$blah="\u56DE\u590D"; не работает?

Нет,Язык ничего не знает о юникоде.В PHP строки являются байтовыми массивами.Следовательно, способ выражения кодовых точек юникода в сценарии PHP зависит от кодировки, которую вы хотите использовать.Для UTF-8 это будет "\xE5\x9B\x9E\xE5\xA4\x8D", для UTF-16 - старший порядковый номер "\x56\xDE\x59\x0D" и т. Д.

Могу ли я преобразовать U+56DE U+590D в его однобайтовую последовательность (возможно,5-6 символов), а затем искать его через strpos?Я не могу понять, как преобразовать его в байты, если это так.

Для первой части, да, т. Е. Для преобразования U+56DE U+590D в байты, требуется уточнение.Это кодовые единицы UTF-16 или кодовые точки Unicode?Например, как представляется ??U+D869 U+uDED6 или U+2A6D6?Если они являются единицами кода Unicode, их тривиально кодировать в UTF-16.Для UTF-16 с прямым порядком байтов это просто "\x56\xDE\x59\x0D".В противном случае все еще тривиально кодировать их в UTF-32, но для того же в UTF-16 (или UTF-8) требуется немного больше работы.

Во второй части продолжайте читать.

Частично проблема в том, что я не знаю, как указать код для использования в strpos, и я не знаю, должен ли PHP быть скомпилирован с какой-либо специальной поддержкой кода, илиесли мне придется использовать mb_strpos, которого я пытаюсь избежать, поскольку он также может быть недоступен.

Что вы пытаетесь сделать?Зачем вам нужно найти позицию в строке?strpos даст вам смещение в байтах для данной строки (опять же, интерпретируется в двоичной форме).Вы пытаетесь обрезать строку?strpos (или даже mb_strpos) означают проблемы в Юникоде - глиф может состоять из нескольких единиц кода, поэтому вы рискуете вырезать часть глифа.Я не могу вам больше советовать, если вы не скажете, что пытаетесь сделать.

1 голос
/ 23 августа 2010

Вы написали «может быть недоступно». Я предлагаю вам попробовать mb_strpos .

...