Internet Windows Android
Kengaytirish

PHP matnni kodlashni aniqlash - mavjud echimlarning umumiy ko'rinishi va yana bitta velosiped. PHP matnni kodlashni aniqlash - mavjud echimlarga umumiy nuqtai va yana bir Php Bike Windows sahifa kodlash 1251

Vazifaga duch keldik - sahifani/matnni/qanday kodlashni avtomatik aniqlash. Vazifa yangi emas va ko'plab velosipedlar allaqachon ixtiro qilingan. Maqolada kichik ko'rib chiqish tarmoqda topilgan - qo'shimcha ravishda o'zimning taklifim, menimcha, munosib yechim.

1. Nima uchun mb_detect_encoding() emas?

Qisqasi, u ishlamaydi.

Keling, tomosha qilaylik:
// Kirish - CP1251 da kodlangan ruscha matn $string = iconv("UTF-8", "Windows-1251", "U Anna Pavlovnaga yaqinlashib, uning qo'lini o'pdi va xushbo'y va porlab turgan kal boshini taklif qildi va xotirjam o'tirdi. divan."); // Keling, md_detect_encoding() bizga nima berishini ko'rib chiqaylik. Birinchi $strict = FALSE var_dump(mb_detect_encoding($string, array("UTF-8")))); // UTF-8 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251")))); // Windows-1251 var_dump(mb_detect_encoding($string, array("UTF-8", "KOI8-R")))); // KOI8-R var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R")))); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "ISO-8859-5")))); // ISO-8859-5 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R", "ISO-8859-5")))); // ISO-8859-5 // Endi $strict = TRUE var_dump(mb_detect_encoding($string, array("UTF-8"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "KOI8-R"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R"), TRUE)); // FALSE var_dump(mb_detect_encoding($string, array("UTF-8", "ISO-8859-5"), TRUE)); // ISO-8859-5 var_dump(mb_detect_encoding($string, array("UTF-8", "Windows-1251", "KOI8-R", "ISO-8859-5"), TRUE)); // ISO-8859-5
Ko'rib turganingizdek, chiqish to'liq tartibsizlikdir. Funktsiya nima uchun bunday harakat qilishini tushunmasak nima qilamiz? To'g'ri, biz google. Ajoyib javob topildi.

Nihoyat mb_detect_encoding() dan foydalanishga bo'lgan barcha umidlarni yo'q qilish uchun siz mbstring kengaytmasi manbalariga kirishingiz kerak. Shunday ekan, yeng shima, ketaylik:
// ext/mbstring/mbstring.c:2629 PHP_FUNCTION(mb_detect_encoding) ( ... // qator 2703 ret = mbfl_identify_encoding_name(&string, elist, size, strict); ...
Ctrl + bosing:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:643 const char* mbfl_identify_encoding_name(mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict) ( const mbfl_encoding *encoding; elflists, encoding (_string) , qattiq); ...
Ctrl + bosing:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:557 /* * kodlashni aniqlash */ const mbfl_encoding * mbfl_identify_encoding (mbfl_string *string, enum mbfl_no_encoding *elist, int elistsz, int strict) ( ...
Maqolani keraksiz manbalar bilan to'sib qo'ymaslik uchun men usulning to'liq matnini joylashtirmayman. Qiziqqanlar o'zlari ko'radi. Bizni 593-qator raqami qiziqtiradi, bu erda belgi kodlashga mos keladimi-yo'qmi tekshiriladi:
// ext/mbstring/libmbfl/mbfl/mbfilter.c:593 (*filtr->filtr_funksiyasi)(*p, filtr); if (filtr-> bayroq) ( bad++; )
Mana bir baytli kirill uchun asosiy filtrlar:

Windows-1251 (asl sharhlar saqlanib qolgan)
// ext/mbstring/libmbfl/filters/mbfilter_cp1251.c:142 /* bularning barchasi hozir juda xunuk! */ statik int mbfl_filt_ident_cp1251(int c, mbfl_identify_filter *filtr) (agar (c >= 0x80 && c)< 0xff) filter->bayroq = 0; boshqa filtr->

KOI8-R
// ext/mbstring/libmbfl/filters/mbfilter_koi8r.c:142 statik int mbfl_filt_ident_koi8r(int c, mbfl_identify_filter *filtr) ( agar (c >= 0x80 && c)< 0xff) filter->bayroq = 0; else filter-> bayroq = 1; /* bu emas */ qaytish c; )

ISO-8859-5 (bu erda hamma narsa qiziqarli)
// ext/mbstring/libmbfl/mbfl/mbfl_ident.c:248 int mbfl_filt_ident_true(int c, mbfl_identify_filter *filtr) (qaytish c; )
Ko'rib turganingizdek, ISO-8859-5 har doim TRUE ni qaytaradi (FALSE ni qaytarish uchun siz filter-> bayroq = 1 ni o'rnatishingiz kerak).

Filtrlarga qaraganimizda hammasi joyiga tushdi. CP1251 KOI8-R dan farq qilmaydi. Umuman olganda, ISO-8859-5, agar u kodlashlar ro'yxatida bo'lsa, u har doim to'g'ri deb topiladi.

Umuman olganda, muvaffaqiyatsiz. Bu tushunarli - faqat belgilar kodlari bilan umumiy holatda kodlashni bilib bo'lmaydi, chunki bu kodlar turli xil kodlashlarda kesishadi.

2. Google nima beradi

Google esa har xil nopoklikni beradi. Men bu yerga manbalarni ham joylamayman, agar xohlasangiz o'zingiz ko'ring (http:// dan keyin bo'sh joyni olib tashlang, matnni havola sifatida emas, balki qanday ko'rsatishni bilmayman):

http://deer.org.ua/2009/10/06/1/
http://php.su/forum/topic.php?forum=1&topic=1346

3. Habr qidiruvi

1) yana belgilar kodlari: habrahabr.ru/blogs/php/27378/#comment_710532

2) menimcha, juda qiziqarli yechim: habrahabr.ru/blogs/php/27378/#comment_1399654
Havoladagi sharhlarda ijobiy va salbiy tomonlari. Shaxsan men bu yechim faqat kodlashni aniqlash uchun ortiqcha deb o'ylayman - bu juda kuchli bo'lib chiqdi. Undagi kodlashning ta'rifi - yon ta'sir sifatida).

4. Aslida mening qarorim

Oldingi bo'limdagi ikkinchi havolani ko'rish paytida g'oya paydo bo'ldi. Fikr quyidagicha: biz katta ruscha matnni olamiz, turli harflarning chastotalarini o'lchaymiz va kodlashni aniqlash uchun ushbu chastotalardan foydalanamiz. Oldinga qarab, men katta va kichik harflar bilan bog'liq muammolar bo'lishini darhol aytaman. Shuning uchun, men harf chastotalari misollarini joylashtiraman (keling, uni "spektr" deb ataymiz) katta-kichik va kichik harflarsiz (ikkinchi holda, men bir xil chastotali kichik harfga kattaroq harf qo'shdim va barcha katta harflarni o'chirib tashladim) . Ushbu "spektrlarda" chastotasi 0,001 dan kam bo'lgan barcha harflar va bo'sh joy kesilgan. "Urush va tinchlik" filmini qayta ishlaganimdan keyin nimaga erishdim:

Katta-kichik harflarga sezgir "spektr":
Bir qator ("O" = 0.09524209893009, "E" => 0.0559981313131413131318913711162 "," 0.002111111 " "=> 0,0014044332975731," O F П "=> 0,0018574762967903", "=> 0.0015961610948418", "=> 0,0013188987793209," A "=> 0,0012623590130186," K "=> 0,0011804488387602," M "=> 0,001061932790165)

Katta-kichik harf sezgir emas:
Array ( "O" => 0,095249209893009, "O" => 0,095249209893009, "E" => 0,06836817536026, "E" => 0,06836817536026, "A" => 0,067481298384992, "a" => 0,067481298384992, "va" => 0,055995027400041 "va" => 0,055995027400041, .... "C" => 0,0029893589260344, "C" => 0,0029893589260344, "щ" => 0,0024649163501406, "щ" => 0,0024649163501406, "E" => 0,002252892226507, "E" => 0,002252892226507, "F" => 0,0015961610948418, "F" => 0,0015961610948418,)

Turli xil kodlashdagi spektrlar (massiv kalitlari - tegishli kodlashdagi tegishli belgilarning kodlari):

Keyinchalik. Biz noma'lum kodlash matnini olamiz, biz tekshiradigan har bir kodlash uchun joriy belgining chastotasini topamiz va ushbu kodlashni "reyting" ga qo'shamiz. Eng yuqori reytingga ega bo'lgan kodlash, ehtimol, matnli kodlashdir.

$encodings = array("cp1251" => "specter_cp1251.php" talab qiladi, "koi8r" => "specter_koi8r.php", "iso88595" => "specter_iso88595.php" talab qilinadi); $enc_rates = massiv(); uchun ($i = 0; $i< len($str); ++$i) { foreach ($encodings as $encoding =>$char_specter) ( $enc_rates[$encoding] += $char_specter)]; ) var_dump($enc_rates);
Ushbu kodni o'zingiz ishga tushirishga urinmang - u ishlamaydi. Buni psevdokod deb o'ylashingiz mumkin - maqolani chalkashtirib yubormaslik uchun tafsilotlarni o'tkazib yubordim. $char_specter faqat pastebinda havola qilingan massivlardir.

natijalar
Jadvalning satrlari matn kodlash, ustunlar esa $enc_rates massivining mazmunidir.

1) $str = "Ruscha matn";
0,441 | 0,020 | 0,085 | Windows-1251
0,049 | 0,441 | 0,166 | KOI8-R
0,133 | 0,092 | 0,441 | ISO-8859-5

Hammasi ajoyib. Haqiqiy kodlash allaqachon boshqalarga qaraganda 4 baravar yuqori reytingga ega - bu shunday qisqa matnda. Uzunroq matnlar uchun nisbat taxminan bir xil bo'ladi.


cp1251 | koi8r | iso88595 |
0,013 | 0,705 | 0,331 | Windows-1251
0,649 | 0,013 | 0.201 | KOI8-R
0,007 | 0,392 | 0,013 | ISO-8859-5

Voy! To'liq bo'tqa. Chunki CP1251 dagi katta harflar odatda KOI8-R dagi kichik harflarga mos keladi. Va kichik harflar katta harflarga qaraganda ko'proq ishlatiladi. Shunday qilib, biz CP1251-dagi bosh harflar qatorini KOI8-R deb belgilaymiz.
Buni qilishga urinish katta-kichik-kichik-katta sezgir emas (“spektralar” katta-kichik harflarni sezmaydi)

1) $str = "Ruscha matn";
cp1251 | koi8r | iso88595 |
0,477 | 0,342 | 0,085 | Windows-1251
0,315 | 0,477 | 0,207 | KOI8-R
0,216 | 0,321 | 0,477 | ISO-8859-5

2) $str = "STRING CAPSOM RUSSIAN MATN";
cp1251 | koi8r | iso88595 |
1.074 | 0,705 | 0,465 | Windows-1251
0,649 | 1.074 | 0.201 | KOI8-R
0,331 | 0,392 | 1.074 | ISO-8859-5

Ko'rib turganingizdek, to'g'ri kodlash katta-kichik harflarga sezgir bo'lgan "spektrlar" bilan barqaror ravishda olib keladi (agar qatorda oz miqdorda bo'lsa). Bosh harflar) va katta-kichik harflarni sezmaydi. Ikkinchi holda, katta-kichik harflarga sezgir bo'lmaganlar bilan, etakchi, albatta, unchalik ishonchli emas, lekin hatto kichik torlarda ham barqaror. Shuningdek, siz harflarning og'irligi bilan o'ynashingiz mumkin - masalan, ularni chastotaga nisbatan chiziqli bo'lmagan holga keltiring.

5. Xulosa

Mavzu UTF-8 bilan ishlashni qamrab olmaydi - bu erda hech qanday asosiy farq yo'q, faqat belgilar kodlarini olish va qatorni belgilarga bo'lish biroz uzoqroq / murakkabroq bo'ladi.
Bu g'oyalar nafaqat kirill kodlashlariga ham kengaytirilishi mumkin, albatta - savol faqat tegishli tillar / kodlashlarning "spektrlarida".

P.S. Agar bu juda zarur/qiziq bo'lsa, men to'liq ishlaydigan kutubxonaning ikkinchi qismini GitHub-ga joylashtiraman. Garchi men postdagi ma'lumotlar bunday kutubxonani tezda yozish va o'z ehtiyojlaringizga moslashish uchun etarli ekanligiga ishonaman - rus tili uchun "spektr" belgilangan, uni barcha kerakli kodlashlarga osongina o'tkazish mumkin.

Keling, avvalgi darslarda yaratgan HTML sahifamizga qaytaylik va endi uning matni saqlanadigan kodlashni o'rnatamiz.

Matn kodlashni o'zgartirishning ikkita usuli haqida gapirmoqchiman. Qoida tariqasida, men ulardan amalda foydalanaman va ular o'zlarini yaxshi isbotladilar.

Matn kodlashni o'zgartirishning eng ishonchli usuli - bu Bloknot dasturlari++. Qoida tariqasida, bu usul har doim ishonchli ishlaydi va eng qiyin muammolarni hal qilish uchun ishlatilishi mumkin.

1 yo'l. Notepad++ yordamida

Shunday qilib, matn kodlashni o'zgartirish uchun bizga maxsus kerak matn muharriri, bu notepad++ deb ataladi.

Bu bepul va uni ushbu saytdan yuklab olish mumkin:

Ushbu dastur yordamida HTML sahifasini oching va "Kodlashlar" asosiy menyusiga o'ting.

O'zgartirmoqchi bo'lgan kodlashni tanlang va faylni saqlang.

Hammasi shu. Dastur juda yaxshi va boshqa muqobillardan farqli o'laroq, u kodlashni mutlaqo o'zgartiradi.

2 yo'l. Dreamweaver universal kod muharriridan foydalanish.

Agar siz Dreamweaver universal kod muharririda ishlayotgan bo'lsangiz, matn ko'rsatiladigan kodlashni belgilash imkoniyati ham mavjud.


Buni "Tahrirlash - Sahifa xususiyatlari" asosiy menyusi yordamida ham qilishingiz mumkin.


Keyin, "Ism / kodlash" bo'limida sizga kerak bo'lgan kodlashni tanlang. Ko'pincha bu Unicode kodlash (UTF-8) bo'ladi.

Yangi html hujjatini yaratishda bu usul yaxshi ishlaydi, lekin agar siz mavjud faylni kodlashni o'zgartirayotgan bo'lsangiz, unda birinchi usuldan foydalangan ma'qul. Bunday holda, u yaxshiroq ishlaydi.

Ushbu operatsiyani kompyuteringizda bajaring.

Biroq, html sahifasi uchun matn kodlashni ko'rsatishning o'zi etarli emas. Uning normal ishlashi uchun siz yana bir narsani qilishingiz kerak: brauzerga matn qaysi kodlashda yozilganligini ayting.

To'satdan oddiy skript ishlamay qoldi. Skriptning vazifasi HTML sahifasini (brauzer o'yinidan) olish va oddiy iboralar yordamida ma'lumotlarni olishdir. Men uchun, yangi boshlovchi sifatida, bu voqea sarosimaga tushdi va ozgina vahima qo'zg'atdi: axir, kecha hammasi ishlayotgan edi! Nima bo'ldi?
Men PHP ning ba'zi funktsiyalarini yaxshilab tushunishim kerak edi.

Kod juda ibtidoiy edi:

$pattern =; $url = "http://www.heroeswm.ru/pl_info.php?id=($id)"; $html = file_get_contents ($url); preg_match ($pattern, $html, $matches); if (isset ($matches [ 1 ] ) ) echo $mos [ 1 ] ; Aks holda echo "topilmadi" ;

$pattern = "#Hat yozish(.*)Jang darajasi#is"; $url = "http://www.heroeswm.ru/pl_info.php?id=($id)"; $html = file_get_contents($url); preg_match($pattern, $html, $mos); agar (isset($ mos keladi)) echo $ mos kelsa; Aks holda echo "topilmadi";

Oddiy muntazam ifoda yordamida ma'lumotlarni olish va tahlil qilish.
Aytishim kerakki, bu kod biroz o'zgartirish natijasidir. Asl versiyada muntazam ifoda HTML teglarini qidirdi. Ammo endi men rus tilidagi ikkita ibora o'rtasida bo'lak topishim kerak edi. Men qidiruv shabloniga ruscha so'zlarni qo'shdim va aynan shu o'zgarish juda muhim bo'ldi.

Va endi tartibda.
O'yin sayti www.heroeswm.ru sahifalarni kodlashda beradi g'alaba qozonish - 1251. Mening serverimda kodlash mavjud UTF-8, shuning uchun barcha skriptlar mavjud UTF-8 BOMsiz.
HTML teglari bo'yicha qidiruvga ega original skript kodlashlardagi farqga qaramay, to'g'ri ishladi, lekin qidiruv shabloniga kirillcha belgilar qo'shganimda, men qidirishni va topishni to'xtatdim. Mening vazifamda muammoni chetga surib qo'yish va boshqa shablonni tanlash juda oson - ruscha so'zlarsiz, lekin ko'p hollarda bu mumkin emas. Shuning uchun men buni to'g'ri qilishga qaror qildim: kodlashlar orasidagi asosiy farq nima nega qo'ng'iroq qiladi muntazam iboralarning noto'g'ri ishlashi, va ayni paytda qanday funktsiyalar ta'sir qiladi kodlashlardagi farq va uni qanday aylanib o'tish kerakligi sababli.

Ma'lumotlarni olish uchun men quyidagi sintaksisga ega file_get_contents() funksiyasidan foydalandim:

ip file_get_contents( ip$filename) , bu erda $filename - o'qilayotgan faylning nomi.
Agar ma'lumotlar muvaffaqiyatli qabul qilinmasa, satr yoki bool(noto'g'ri) qaytaradi.

Eng aniq kodlash farqi g'alaba qozonish - 1251 Va UTF-8 ular bilan kodlash mumkin bo'lgan belgilar soni. Birinchisi (va shunga o'xshash) faqat 255 ga bo'ysunadi, chunki har bir belgi bir bayt bilan kodlangan.

Ikkinchisining yordami bilan siz milliy alifbo harflari, arab harflari va ierogliflarni o'z ichiga olgan juda katta belgilar to'plamini o'tkazishingiz mumkin. Belgilar to'plamining bunday kengayishiga belgilar bir emas, balki ikki (ko'p belgilar uchun) yoki undan ko'p (to'rttagacha) bayt bilan kodlanganligi sababli erishiladi. Shuning uchun kodlash UTF-8(va shunga o'xshashlar) bir baytlilardan farqli ravishda ko'p yoki ko'p baytli deb ataladi, masalan g'alaba qozonish - 1251.

Bunday keng belgilar to'plami bilan, UTF-8 bitta saytda turli alifbo harflaridan foydalanishga ruxsat beribgina qolmay, balki kirill alifbosi bilan kodlashlar mavjud bo'lganda ham rus tilidagi sayt to'g'ri ko'rsatilishiga ma'lum kafolat beradi ( g'alaba qozonish - 1251, KOI8-R, CP866, ISO 8859-5 va hokazo) hatto gumon qilmang: Yaponiyada, Koreyada, arab mamlakatlarida va hokazo. Bunday ko'p qirralilikning narxi saqlash vaqtida belgilarning biroz kattaroq og'irligi va shunga mos ravishda ularni string funktsiyalari bilan qayta ishlash uchun uzoqroq vaqt bo'ladi. PHP. Aytgancha, aksariyat hollarda ular to'g'ri ishlamaydi. Men shunday muammoga duch keldim: yozilgan skriptning muntazam ifodasi UTF-8, saytdan olingan sahifada menga kerak boʻlgan pastki qatorni, shu jumladan kirill harflarini toʻgʻri topa olmadim. Windows-1251.

Faqat kirill va lotin alifbolaridan foydalanadigan saytlar shunday deb taxmin qilish mantiqan to'g'ri UTF-8 hech narsaga yo'l qo'ymaydi va oddiy tahlilchi juda yaxshi "yashagan" g'alaba qozonish - 1251, lekin bu kodlashlar va ulardan foydalanish bilan do'stlashish kerak bo'lmagan holatlar mavjud string funktsiyalari PHP masalan, loyihani ishlab chiqishda tashqariga chiqmang UTF-8.

String funktsiyalarining noto'g'ri ishlashiga nima sabab bo'ldi?

Yuqorida aytib o'tilganidek, kodlashlar o'rtasidagi asosiy farq belgilar uzunligi. Shuning uchun, baytlar kabi belgilar bilan ishlaydigan funktsiyalardan foydalanishda muammolar paydo bo'ladi va qiymatlar baytlarda ham qaytariladi (bu bir baytli kodlash uchun to'g'ri keladi: bitta belgi bir baytga teng).

Masalan, funktsiya

substr ("Tekshirish" , 0 , 5 ); // UTF-8 kodlashdagi matn

substr("Tekshirish", 0, 5); // UTF-8 kodlashdagi matn

kutilgan "Isbotlash" o'rniga "Pr�" ni qaytaradi: in UTF-8 Kirillcha belgilar ikki baytda kodlangan, buning natijasida biz "krakozyabr" ni ko'ramiz - faqat "o" belgisining birinchi bayti.

Shunday qilib, ko'p hollarda satrlar bilan ishlash UTF-8 maxsus funktsiyalardan foydalanishni talab qiladi (masalan, kengaytmadan PHP mbstring), va ba'zan ikkalasi ham (masalan, HTTP sarlavhasida satr hajmini baytlarda o'tkazish uchun siz strlen() ni tark etishingiz kerak va belgilar sonini hisoblash uchun mb_strlen() qo'shishingiz kerak bo'ladi).

Kengaytma funksiyalari bilan almashtirilishi kerak bo'lgan tez-tez ishlatiladigan funksiyalar sintaksisi PHP mbString:

int strlen( ip$string) - satr uzunligini qaytaradi, yoki satr bo'sh bo'lsa 0 ni qaytaradi.

int strpos( ip$haystack, aralashgan$needle) - $haystack pastki satrida $needle satrining birinchi paydo boʻlgan oʻrnini qaytaradi yoki FALSE topilmasa.

stripos oldingi funksiyaga o'xshaydi, faqat qidiruv katta-kichik harflarga sezgir emas.

ip substr( ip$string , int$start [, int $length ]) - ko'rsatilgan belgilar pozitsiyasidan boshlab pastki qatorni tanlash imkonini beradi va uchinchi parametrni ko'rsatishda - ma'lum uzunlik.

Ularning analoglari ko'p baytli kodlashlarda ishlash uchun mo'ljallangan: mb_strlen , mb_strpos , mb_stripos va mb_substr .

Albatta, matn bilan ishlash uchun yana ko'plab funktsiyalar mavjud. Men faqat eng mashhurlarini kiritdim.

Muntazam iboralar bilan ishlash funktsiyalari, muntazam ifoda tomonidan ko'rsatilgan niqobga mos keladigan pastki qatorni (pastki satrlarni) qidirish uchun mo'ljallangan.

int oldingi_match( ip$pattern, ip$mavzu, massiv&$ mos keladi)

int preg_match_all( ip$pattern, ip$mavzu massiv&$ mos keladi).

$subject matni muntazam ifoda tomonidan belgilangan $patternga mos keladi. Qidiruv natijasi $matches o'zgaruvchisiga yoziladi. Funksiya naqsh bilan topilgan mosliklar sonini qaytaradi, xato bo'lsa, u qaytadi FALSE.

Shaklni moslashtirish uchun ko'p baytli kodlashlardan foydalanish muntazam iboralar, siz ularga /u modifikatorini qo'shishingiz yoki mb_ereg* funksiyalar guruhidan foydalanishingiz kerak bo'ladi.

Nima qilish kerak?

Birinchi bo'lib kelgan yechim - qayta kodlash UTF-8 qabul qilingan g'alaba qozonish - 1251 ma'lumotlar - bu noqulay tuyuldi. Axir, qayta kodlashdan so'ng, barcha oddiy funktsiyalarni ishlash uchun maxsus funktsiyalar bilan almashtirish kerak bo'ladi UTF-8, yoki /u modifikatoridan foydalanishga harakat qiling (oldinga qarab, bu sizga bitta baytli kodlashdagi satrlar bilan ishlash imkonini beradi, masalan, "satrlar bilan" UTF-8', lekin qatorlar uchun mos emas UTF-8). Mening misolimda faqat bitta preg_match() mavjud, ammo amalda bu kamdan-kam hollarda bo'ladi.

Shunday qilib, men muammoni hal qilyapman: men oddiy preg_match() funksiyalaridan foydalanmoqchiman va buning uchun kiruvchi satrni emas, balki iconv() yordamida qidiruv naqshini qayta kodlamoqchiman.

Funktsiya sintaksisi:
ip iconv($in_charset, $out_charset, $str) - $str satrini $in_charset kodlashdan $out_charset kodlashiga oʻzgartiradi. Asl o'zgaruvchiga ta'sir qilmasdan qayta kodlangan matnni qaytaradi.

Funktsiya yangi kodlashda satrni qaytaradi, lekin satrning kodlanishini o'zgartirmaydi. Shunung uchun

$pattern = "#Hat yozish(.*)Jang darajasi#is"; iconv("UTF-8", "WINDOWS-1251", $pattern); // $pattern original kodlashda qoladi preg_match($pattern, $html, $matches);

ishlamaydi - $pattern asl kodlashda qoldi UTF-8. iconv natijasini o'zgaruvchiga belgilashingiz kerak:

$naqsh = "#Xat yozish(.*)Jang darajasi#is"; $pattern = iconv("UTF-8" , "WINDOWS-1251" , $pattern ); preg_match ($pattern, $html, $matches);

$pattern = "#Hat yozish(.*)Jang darajasi#is"; $pattern = iconv("UTF-8", "WINDOWS-1251", $pattern); preg_match($pattern, $html, $mos);

Endi qidiruv to'g'ri ishlaydi, lekin brauzerga faqat qattiq krakozyabry beradi. Xo'sh, bu erda men nima qilish kerakligini allaqachon bilaman: natijani ishlaydigan kodlashda qayta kodlashingiz kerak UTF-8. Va keyin ikkinchi nuqta paydo bo'ldi, bu menga tushunarsiz edi, garchi men ko'proq tajribaga ega bo'lsam, ehtimol qiyinchiliklarga olib kelmagan bo'lardim: nima uchun iconv () ba'zi o'zgaruvchilarni qayta kodlaydi, lekin boshqalar emas?

$matches oʻzgaruvchisi massiv boʻlib, men iconv($matches) kodini bir marta qayta kodlashdan qochishga harakat qildim. Yana bir bor funktsiya sintaksisining tavsifiga qarayman: albatta, barcha parametrlar massivlar emas, balki satrlar bo'lishi kerak. Ya'ni, qayta kodlanishi kerak bo'lgan barcha massiv qiymatlaridan o'tish va ularni o'zgartirish kerak. kerakli kodlash. Mening misolimda men massivni takrorlamadim, chunki meni butun massiv emas, balki bitta qiymat qiziqtirdi. Men uni iconv() funktsiyasining parametri sifatida ko'rsatdim.

Men nima bilan yakunladim:

// standart kodlashni o'rnating setlocale(LC_ALL, "ru_RU.UTF-8" ); sarlavha ( "Tarkib turi: matn/html; belgilar to'plami = UTF-8"); $naqsh = "#Xat yozish(.*)Jang darajasi#is"; $pattern = iconv("UTF-8" , "WINDOWS-1251" , $pattern ); $url = "http://www.heroeswm.ru/pl_info.php?id=993353"; $html = file_get_contents ($url); preg_match ($pattern, $html, $matches); agar (isset ($matches [ 1 ] ) ) echo $matches [ 1 ] = iconv ("WINDOWS-1251", "UTF-8", $mos [1 ] ); Aks holda echo "topilmadi" ; ?>

Maqola mening yaxshi do'stim tomonidan yozilgan. U matn yozish va tekshirish bilan shug'ullanadi, PHPda dasturlash uning sevimli mashg'ulotidir. Mening blogimda u barcha nashrlarni tuzatadi va bu uning menga blogning 2 yilligi uchun sovg'asi bo'ldi.

Shu kabi nashrlar topilmadi.