Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум Регулярные Выражения

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Определить кодировку текста
 
 автор: Valleri   (10.07.2011 в 14:46)   письмо автору
 
 

Как определить(PНP) принадлежность текста к русской и латинской кодировке, при получении данных формы

  Ответить  
 
 автор: cheops   (10.07.2011 в 14:59)   письмо автору
 
   для: Valleri   (10.07.2011 в 14:46)
 

Можно при помощи регулярных выражений проверить, входит ли в текст хотя бы одна русская буква, если входит - это русский текст, если не входит - это английский текст. Возможно вас заинтересует тема по ссылке http://softtime.ru/forum/read.php?id_forum=6&id_theme=81504.

  Ответить  
 
 автор: Valleri   (10.07.2011 в 15:18)   письмо автору
 
   для: cheops   (10.07.2011 в 14:59)
 

Вот спасибо.
Не по теме, если можно, почему в начале и конце $pattern применяют разные / или | или #...
как правильней, откуда это исходит

  Ответить  
 
 автор: cheops   (10.07.2011 в 15:25)   письмо автору
 
   для: Valleri   (10.07.2011 в 15:18)
 

Это границы регулярного выражения, можно использовать любые символы, но они должны совпадать и экранироваться внутри регулярного выражения. Исходит это из Perl, откуда собственно, этот диалект регулярных выражений и пошел, там регулярные выражения создаются вообще без строк, прямо так и пишут в коде /рег.выр/ (в JavaScript, кстати, похожая ситуация, хотя объект регулярного выражения можно создать и из строки). Традиционными границами являются / и /, но в регулярных выражениях в Web они часто используются, чтобы их постоянно не экранировать, выбирают другие границы.

  Ответить  
 
 автор: Valleri   (10.07.2011 в 16:01)   письмо автору
 
   для: cheops   (10.07.2011 в 15:25)
 

Спасибо. Кажется мелочь, но при изучении голова начинает кипеть от количества объяснений и догадок, собственных иллюзий и вымыслов.
Только хочется добавить в паттерн, если часть текста осмысленная. Человека заменить конечно трудно,еще труднее грамотного заменить и наверное никогда-широко образованного.
Хорошо когда рядом умные люди, хуже когда сливаются в голову оракулоподобная чепуха из всего инета.
Но может как то приблизиться к этому, в случае злостных отклонений от правил, можно?
Как только часть тексата или процент символов на соответствие образцу проверить?
Исходный образец допустим
$pattern = '#[^\s\dа-яa-z]#is'

Задача проверить часть текста на соответствие русской, латинской раскладке слов символов, последовательностей без пробелов( с проверкой длины слов и разбитию если длинные) а не символов?

  Ответить  
 
 автор: cheops   (10.07.2011 в 16:26)   письмо автору
 
   для: Valleri   (10.07.2011 в 16:01)
 

>Задача проверить часть текста на соответствие русской, латинской раскладке символов слов( с
>проверкой длины слов и разбитию если длинные) а не символов?
Для этого нужно добавить границы слова \b и один символ [] превратить в один или более при помощи +
$pattern = '#\b[^\s\dа-яa-z]+\b#is'
Только за условием следите - это выражение вернет true для полностью русского текста, без цифр (как впрочем и для китайского).

PS Регулярные выражения - это спец-язык, довольно сложный (для программистов с опытом программирования на императивных языках). Т.е. чтобы им овладеть, его нужно учить отдельно, решать на нём задачи. С налету и по аналогии с другими языками его не выучишь - нужно долбать серьезно и целенаправленно. Этот форум в свое время появился, чтобы помочь с регулярными выражениями тем, у кого нет на изучение времени, возможности с одной стороны, и чтобы те, кто изучает язык, могли тренироваться, так как без хорошей практики освоить регулярные выражения помоему не реально. Этот язык, как и Perl делал лингвист (очень хороший, с серьезнейшей подготовкой) - поэтому он очень здорово выбивается того, к чему привыкли программисты, зато мощность его просто бесподобна (разумеется на задачах, для которых он спроектирован). Математики любят говорить, что трудная задач имеет два решения: сложное простыми методами и простое сложными методами. Регулярные выражения они из вторых (но времени и усилий на их освоение требуется много, по крайней мере больше, чем на обычные императивные языки).

  Ответить  
 
 автор: Deed   (10.07.2011 в 16:37)   письмо автору
 
   для: cheops   (10.07.2011 в 16:26)
 

>Для этого нужно добавить границы слова \b и один символ [] превратить в один или более при помощи +
>
>Только за условием следите - это выражение вернет true для полностью русского текста, без цифр (как >впрочем и для китайского).
>

Я не понял.
$pattern = '#\b[^\s\dа-яa-z]+\b#is'

Cheops, [^\s\dа-яa-z]... Какое здесь "true для полностью русского текста"???

  Ответить  
 
 автор: cheops   (10.07.2011 в 16:45)   письмо автору
 
   для: Deed   (10.07.2011 в 16:37)
 

Да, это я погорячился, конечно имеется в виду
$pattern = '#\b[а-я]+\b#i'

  Ответить  
 
 автор: Valleri   (10.07.2011 в 17:20)   письмо автору
 
   для: cheops   (10.07.2011 в 16:26)
 

А не повело ли в сторону меня.
Началось с моего вопроса о кодировке.
А сейчас вроде про раскладку клавиатуры идет речь.
Или ту разницы не будет?
Ситуация перед записью в базу, при получении данных формы

  Ответить  
 
 автор: cheops   (10.07.2011 в 18:00)   письмо автору
 
   для: Valleri   (10.07.2011 в 17:20)
 

Кодировку автоматически определять довольно сложно, так как перед вами просто строка (читай набор кодов), как эти коды будете интерпретировать - такая строка и получится. Компьютер не знает осмысленная это строка или нет - он видит только числа/коды. Если раскладку мы еще можем выловить - в разных раскладках от нажатий клавиш разные коды получаются, то с кодировкой уже сложнее (коды одни и те же, но если сказать что это русская кодировка - компьютер будет пытаться их интерпретировать как русский текст, понятия не имея что там на выходе получается) - лучше бы если она была у вас везде одинаковая или поддерживала все языки (например, UTF-8), если в этом есть необходимость.

  Ответить  
 
 автор: Valleri   (10.07.2011 в 18:26)   письмо автору
 
   для: cheops   (10.07.2011 в 18:00)
 

Кодировку не надо определять. То есть вид кодировки всего текста, по одному символу или по группе или по всем не надо определять.
Надо определить, относится ли каждый конкретный символ к символу конкретной кодировки.
Т. е. логико-множественными операциями и соответствиями.
Если какой-то символ не найден образце, то считать, что весь текст не соответствует требованиям.
Наверное я непонятно пишу, но стараюсь добиться понятности

  Ответить  
 
 автор: cheops   (10.07.2011 в 18:53)   письмо автору
 
   для: Valleri   (10.07.2011 в 18:26)
 

Под кодировкой вы что имеете в виду?

PS Кодировка это интерпретация символов, т.е. есть строка кодов
72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33
Вы говорите машине превратить её в английский текст кодировки ASCII, она достает таблицу ASCII и заменяет каждый код на букву, получается
Hello world!
А теперь вы говорите преобразуй следующую последовательность
207, 240, 232, 226, 229, 242, 32, 236, 232, 240, 33
в Windows-866, машина достает таблицу кодировки и пишет
╧ЁштхЄ ьшЁ!
Вы говорите, машине, ой-ой-ёй, что-то не то, ошибочка вышла, нужна кодировка Windows-1251, машина достает эту кодировку и пишет
Привет мир!


Т.е. машина видит только вот это
207, 240, 232, 226, 229, 242, 32, 236, 232, 240, 33
и пока вы ей не скажите как это читать, она ничего с этими цифрами сделать не сможет. Это и есть кодировка - договор о том, как интерпретировать последовательность чисел, справочник из "китайской комнаты".

  Ответить  
 
 автор: Valleri   (10.07.2011 в 19:13)   письмо автору
 
   для: cheops   (10.07.2011 в 18:53)
 

Спасибо за хороший вопрос
Задаем правило, что есть множество, набор символов, который соответствует например Windows-1251
Если хоть один символ из этих
Вызов РѕР±С‰РµРґРѕСЃС‚СѓРїРЅРѕРіРѕ  и Привет мир!,
является не читабельным в Windows-1251, то считать весь текст бракованным и отказать программно пользователю.
В этом наборе
 Р’ызов РѕР±С‰РµРґРѕСЃС‚СѓРїРЅРѕРіРѕ 

все символы не читабельные в Windows-1251, следовательно весь текст брак
Необходимость вызвана отсутствием модерации или редкостью процесса модерации во времени.
Возможно вопрос у меня кривой.

  Ответить  
 
 автор: cheops   (10.07.2011 в 19:32)   письмо автору
 
   для: Valleri   (10.07.2011 в 19:13)
 

А как вы определите без человека, что они не читабельны? Машина видит цифры - для неё все символы читабельны, так как каждый такой символ - это число (причем с этим числом связано несколько символов из разных кодировок, которые можно однозначно выбрать, только если задана кодировка). Вернее даже не так, она видит только числа и их последовательность - символы ей нужны, чтобы мы понимали результат её работы, ей самой они нафиг не вперлись - лишние вычисления. То что вы сходу определяете читаем текст или нет является результатом 4-млрд эволюции, зрения, распознавания образов, разума, и его многолетнего обучения. Компьютеры по другому устроены, научить их распознавать образы довольно тяжело. Да и глупо преобразовывать текст в растр и решать задачу распознавания образов. Обычно такие штуки строят на патернах, словарях... однако, если текста мало или если текст одинаков для разных кодировок - задачу вообще нельзя решить. Если бы эта задача решалась элементарно, то в HTML не нужно было бы указывать кодировку с META-тэге, а браузер не содержал бы внушительные инструменты для управления кодировкой. Есть библиотеки, которые решают данную задачу (когда это возможно), но они не без греха. Понятно, что в русском языке одни символы часто следуют после других, одни символы никогда не могут следовать после други (жи, ши пиши с и...), однако и грамматические ошибки исключать нельзя. В общем задача довольно серьезная и однозначного решения не имеет. Вот есть однобайтовое число (код) 47 - какая это кодировка? Да какая угодно.

  Ответить  
 
 автор: Valleri   (10.07.2011 в 20:32)   письмо автору
 
   для: cheops   (10.07.2011 в 19:32)
 

Я не могу сходу привести пример, но из вашего примера попробую пояснить или прояснить себе

в Windows-866, машина достает таблицу кодировки и пишет
╧ЁштхЄ ьшЁ!

Є эта буква не читабельна.
Наверное это 32 и может быть в Windows-866 нет такого кода.
или
ї

Я не знаю какой код у этой краказябры, но в Windows-1251 нет такой буквы, так как наверное нет такого кода Windows-1251
Я поищу коды и их символы и попробую понять.

  Ответить  
 
 автор: cheops   (10.07.2011 в 21:02)   письмо автору
 
   для: Valleri   (10.07.2011 в 20:32)
 

Это 242, 32 - это пробел. Можно, конечно, попытаться, но что вы будете делать, если у вас в руках окажется один символ? Все-равно задача имеет ограничения и требует мало-мальски хоть какого-то объемного текста.

  Ответить  
 
 автор: Valleri   (10.07.2011 в 21:14)   письмо автору
 
   для: cheops   (10.07.2011 в 21:02)
 

Я примера не могу подобрать, не найти таблицы соответствия.
Любая задача решается в постановке. Математики говорят, прежде чем решать задачу надо прочитать условия.
Один символ - не бросается в глаза, его не пропустит ограничение по длине. А вот в сотне символах, хоть один найдется.
Кстати ваше решение
$pattern = '#\b[^\s\dа-яa-z]+\b#is'

Не пропускает вроде символы
Вызов РѕР±С‰РµРґРѕСЃС‚СѓРїРЅРѕРіРѕ 

Ваше решение обладает некоторой универсальностью, это уже плюс. Оно не обладает всеобщей божественной универсальностью. Но оно решает задачу в постановке. Дальнейшая точность может требует огромных усилий а может и нет
Я не ас, мне трудно подбирать слова и объяснения для понимания, но вроде работает
Сами машинные коды наверное не играют роли похоже для понимания, важно что
$pattern = '#\b[^\s\dа-яa-z]+\b#is'

Не может пропустить краказябры
(Кажется запуталось все)

  Ответить  
 
 автор: cheops   (10.07.2011 в 21:06)   письмо автору
 
   для: Valleri   (10.07.2011 в 20:32)
 

>Я поищу коды и их символы и попробую понять.
Искать их не обязательно берите любую строку - это массив символов, код символа можно получить при помощи функции ord().

  Ответить  
 
 автор: Deed   (10.07.2011 в 22:29)   письмо автору
 
   для: cheops   (10.07.2011 в 21:06)
 


   <?
   define
('LOWERCASE',3);
   
define('UPPERCASE',1);
   function 
detect_cyr_charset($str) {
       
$charsets = Array(
                         
'k' => 0,
                         
'w' => 0,
                         
'd' => 0,
                         
'i' => 0,
                         
'm' => 0
                         
);
       for ( 
$i 0$length strlen($str); $i $length$i++ ) {
           
$char ord($str[$i]);
           
//non-russian characters
           
if ($char 128 || $char 256) continue;

           
//CP866
           
if (($char 159 && $char 176) || ($char 223 && $char 242))
               
$charsets['d']+=LOWERCASE;
           if ((
$char 127 && $char 160)) $charsets['d']+=UPPERCASE;

           
//KOI8-R
           
if (($char 191 && $char 223)) $charsets['k']+=LOWERCASE;
           if ((
$char 222 && $char 256)) $charsets['k']+=UPPERCASE;

           
//WIN-1251
           
if ($char 223 && $char 256$charsets['w']+=LOWERCASE;
           if (
$char 191 && $char 224$charsets['w']+=UPPERCASE;

           
//MAC
           
if ($char 221 && $char 255$charsets['m']+=LOWERCASE;
           if (
$char 127 && $char 160$charsets['m']+=UPPERCASE;

           
//ISO-8859-5
           
if ($char 207 && $char 240$charsets['i']+=LOWERCASE;
           if (
$char 175 && $char 208$charsets['i']+=UPPERCASE;

       }
       
arsort($charsets);
       return 
key($charsets);
   }
   
?>

  Ответить  
 
 автор: Deed   (10.07.2011 в 15:30)   письмо автору
 
   для: cheops   (10.07.2011 в 14:59)
 

А что делать, если пишут нам из китайской провинции Сянган?

  Ответить  
 
 автор: cheops   (10.07.2011 в 15:34)   письмо автору
 
   для: Deed   (10.07.2011 в 15:30)
 

А что требуется? Чтобы не писали? Или что-то другое?

  Ответить  
 
 автор: Deed   (10.07.2011 в 16:28)   письмо автору
 
   для: cheops   (10.07.2011 в 15:34)
 

Добрый день!
Да вот, пытаюсь сделать смену языка интерфейса в зависимости от предпочтений посетителя. То есть, заполнил он форму на китайском - получил соответствующую куку, по которой и будет выдаваться инфа.

  Ответить  
 
 автор: cheops   (10.07.2011 в 16:48)   письмо автору
 
   для: Deed   (10.07.2011 в 16:28)
 

Хм... а между сколькими языками осуществляется переключение?

  Ответить  
 
 автор: Deed   (10.07.2011 в 22:22)   письмо автору
 
   для: cheops   (10.07.2011 в 16:48)
 

Да есть, в принципе, решение:
http://heel.org.ua/php-functions/mb-detect-encoding.html - mb_detect_encoding

  Ответить  
 
 автор: .....   (10.07.2011 в 22:06)
 
   для: Deed   (10.07.2011 в 16:28)
 

В утф.8 (точнее в кодировках представляющих юникод) можно пытаться определить используемые языками алфавиты ... с некоторой долей вероятности, так.же как не всегда по обрывку текста можно утверждать что кодировка утф.8

если язык текста неизвестен, однобайтные кодировки различимы ... перебором всех кодировок и узнаванием знакомых слов :)

  Ответить  
 
 автор: Deed   (10.07.2011 в 22:23)   письмо автору
 
   для: .....   (10.07.2011 в 22:06)
 

Та да :)
http://forum.grodno.net/index.php?topic=61739.0

  Ответить  
 
 автор: .....   (10.07.2011 в 22:52)
 
   для: Deed   (10.07.2011 в 22:23)
 

То.что юзер вводит текст в форме с Вашей странички, (и если кодировку странице задаёт браузер а не юзер), в какой.то степени может принуждать отсылать утф.8.

Сложность в том что например кириллический алфавит это русский, украинский, беларусский, сербский, ... и многие другие языки. Символы это всего.лишь символы, но есть исключения (то что например отделены идентичные печатные символы в латинице )

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования