Strpos تبحث عن Unicode في PHP (والتعامل مع UTF-8)
-
30-09-2019 - |
سؤال
أواجه مشكلة في التعامل مع بحث بسيط عن سلسلة unicode من حرفتين (الإبرة) داخل سلسلة أخرى (The Haystack) التي قد تكون أو لا تكون 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؟ لا يمكنني معرفة كيفية تحويله إلى بايت إذا كان الأمر كذلك.
كيف تحدد Unicode مضمّن في PHP على أي حال؟ أعني خارج PRCE؟
$blah="\u56DE\u590D";
لا يعمل؟
شكرا على أي أفكار!
المحلول
أولاً ، سؤالك منظم بشكل سيئ. لديها عدة أسئلة في عدة نقاط. من المحتمل أن تحصل على المزيد من الإجابات إذا استخدمت بنية أكثر وضوحًا: 1) صف المهمة التي تحاول إنجازها ، 2) القيود/المتطلبات ، 3) الإستراتيجية التي فكرت فيها ، 4) الصعوبات التي وجدتها بهذه الاستراتيجية/ يمسح الديون.
ومع ذلك ، سأبدأ في النهاية:
$blah="\u56DE\u590D";
لا يعمل؟
لا. اللغة لا تعرف أي شيء عن يونيكود. في PHP ، السلاسل هي صفائف البايت. لذلك ، تعتمد كيفية التعبير عن نقاط رمز Unicode في البرنامج النصي PHP على الترميز الذي تريد استخدامه. بالنسبة لـ UTF-8 ، سيكون الأمر كذلك "\xE5\x9B\x9E\xE5\xA4\x8D"
, ، بالنسبة لـ UTF-16 Big Endian سيكون "\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 Big Endian ، إنه فقط "\x56\xDE\x59\x0D"
. خلاف ذلك ، لا يزال تافها ترميزها UTF-32 ، ولكن الأمر يتطلب المزيد من العمل لفعل الشيء نفسه في UTF-16 (أو UTF-8).
للجزء الثاني ، استمر في القراءة.
جزء من المشكلة هو أنني لا أعرف كيفية تحديد الرمز للاستخدام في
strpos
, ، ولا أعرف ما إذا كان يجب تجميع PHP بأي دعم خاص للرمز ، أو إذا كان علي استخدامmb_strpos
الذي أحاول تجنبه لأنه قد لا يكون متاحًا أيضًا.
ماذا تحاول أن تفعل؟ لماذا تحتاج إلى العثور على موقف في سلسلة؟ strpos
سوف يعطيك إزاحة بايت لسلسلة معينة (مرة أخرى ، تم تفسيرها في شكل ثنائي). هل تحاول قص سلسلة؟ strpos
(او حتى mb_strpos
) يعني المتاعب في Unicode - يمكن تشكيل الرسول الرسمية بواسطة عدة وحدات رمز ، لذلك تخاطر بجزء من الرسول الرسمية. لا أستطيع أن أنصحك أكثر إلا إذا أخبرت بما تحاول القيام به.
نصائح أخرى
لقد كتبت "قد لا تكون متاحة". أقترح عليك المحاولة mb_strpos.