Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Проблемы с регэкспом на русском


Автор: Innuendo 1.10.2006, 14:06
Есть рег... на русском. Просто на русском заводить нельзя, поэтому ввожу через /uXXXX.. И вот чё-то он не находит совпадение рега со стрингой.
Вот тестовый пример, тут мы ищем аналоги слов "емэйл" (с разными типами написания)
Код

var test = /(е|и)\s*(-)?\s*м(э|е)(й|и)л/gi; //рег на русском
var test2 = /(\u0435|\u0438)\u005cs*(-)?\u005cs*\u043c(\u044d|\u0435)(\u0439|\u0438)\u043b/gi; 
                                                              // этот же рег но в кодировке
var test3 = eval("'"+test2+"'"); //переводи рег из кодировки в нормальный вид
test3 = eval(test3); //превращаем его в рег (теперь test3.constructor = regExp)
alert(test==test3); //но они не равны всё таки
alert(test+"\n"+test3); //просим вывести 2 рега.. первый как-то изменился =)
                                     //кстати, если следующие 2 строки убрать, то первый рег не
                                     //изменится в этом алерте
alert(test.test("мой и-мейл")); //совпал ли первый рег с фразой? - Да.
alert(test3.test("мой и-мейл")); //совпал ли второй рег с фразой? - Нет
                                                   // а почему?

Автор: Sardar 1.10.2006, 14:42
Цитата(Innuendo @  1.10.2006,  13:06 Найти цитируемый пост)
\s*(-)?\s*

Убери \s*, ошибочных совпадений много будет.

Цитата(Innuendo @  1.10.2006,  13:06 Найти цитируемый пост)
var test3 = eval("'"+test2+"'"); //переводи рег из кодировки в нормальный вид

О чём идёт речь?

Цитата(Innuendo @  1.10.2006,  13:06 Найти цитируемый пост)
test3 = eval(test3); //превращаем его в рег (теперь test3.constructor = regExp)
alert(test==test3); //но они не равны всё таки

логика...  smile 

Выход: убирай всё кроме второй и последней строки, в последней замени test3 на test2.

Автор: Innuendo 1.10.2006, 15:45
Цитата(Sardar @  1.10.2006,  14:42 Найти цитируемый пост)
логика...  smile 

Выход: убирай всё кроме второй и последней строки, в последней замени test3 на test2. 

т.е. так?
Код

var test2 = /(\u0435|\u0438)\u005cs*(-)?\u005cs*\u043c(\u044d|\u0435)(\u0439|\u0438)\u043b/gi;
alert(test2.test("мой и-мейл"));

нет совпадения =(

а почему /s* убрать? мне бы желательно чтоб была возможность пробела между тире (если оно есть)

Автор: Sardar 1.10.2006, 16:08
Просто сравни свой и мой реги, обрати внимание на \s:

Код
var test2 = /[\u0435|\u0438]\s*(-)?\s*\u043c[\u044d|\u0435][\u0439\u0438]\u043b/gi;

Также кинь тестовую строку на alert, убедись что там не кракозябры (кодировка выставлена правильно). Рег как и всё строковое работает в юникоде, но твой исходник не в юникоде, браузер декдирует согласно выбранной кодировке. У меня рег выше работает: 

Код
<!-- только что бы ты видел, что там не кракозябры -->
<div id="ttest">мой и-мейл</div>
<script type="text/javascript">
var test2 = /[\u0435|\u0438]\s*(?:-)?\s*\u043c[\u044d|\u0435][\u0439\u0438]\u043b/gi;
alert(test2.test(document.getElementById("ttest").innerHTML));
</script>

Автор: Innuendo 1.10.2006, 20:30
ок.. да.. работает.. Но я не понимаю, объясните плз, почему не работает:
Код

<div id="ttest">мой и-мейл</div>
<input type='button' onclick='test1()' value='test1' />
<input type='button' onclick='test2()' value='test2' />
<script type="text/javascript">
function test1(){
var test2 = /(\u0435|\u0438)\u005cs*(-)?\u005cs*\u043c(\u044d|\u0435)(\u0439|\u0438)\u043b/gi;
alert(test2.test(document.getElementById("ttest").innerHTML));
}
function test2(){
var test2 = /(е|и)\s*(-)?\s*м(э|е)(й|и)л/gi;
alert(test2.test(document.getElementById("ttest").innerHTML));
}
</script>

если реги равны (только один выведен в кодировке, а другой просто на кириллице)

Автор: Sardar 1.10.2006, 21:05
Цитата(Sardar @  1.10.2006,  15:08 Найти цитируемый пост)
обрати внимание на \s

Читай внимательно.

Просто кирилицей реги будут зависеть от кодировки на странице. Впрочем это не проблема, если сервер всегда указывае кодировку правильно.

Автор: Innuendo 1.10.2006, 21:12
ааа. у тебя \s - пишется \s, а у меня \u005cs =)

ну я изменил на \s в моём тесте... и страница отображается в кириллице koi8-r. Я меняю на windows-1251 и всё работает - оба теста - true =)
а почему так происходит с кодировкой? я всего-то эти символы заменил

Автор: Sardar 2.10.2006, 00:02
Цитата(Innuendo @  1.10.2006,  20:12 Найти цитируемый пост)
и страница отображается в кириллице koi8-r. Я меняю на windows-1251 и всё работает - оба теста - true =)

unicode: 2 байта
koi8-r, cp1251: 1 байт

2 байта больше 1 байт, значит:
  2 байта convertTo 1 байт - без проблем
  1 байт convertTo 2 байта - необходимо знать кодировку.

Значит кодировка это функция map(byte) -> unicode char, значит если функция не верна (кодировка не верна), то получим не читабельный в кирилице текст или кракозябры, зависит от того какую кодировку возьмёт браузер. Если и рег и текст на странице заданы в однобайтовой кодировке, то находить инфу он должен всегда, т.к. правила декодирования однобайтовых символов юникод едины для всего исходника.

Но если рег задан как \uHHHH, он уже в юникоде и будет искать одни и те же коды символов (кирилицы) какую ты кодировку странице не ставь.  Ясно что однобайтовый текст будет выдавать разные юникодовские коды символов, в зависимости от выбранной кодировки, т.е. кирилица будет только если кодировка исходника совпадает с выбранной кодировкой. Отсюда должно быть ясно, почему рег не может найти совпадений если кодировка не верна.

Что бы избежать всей этой лажи лучше пользовать UTF-8. Либо всё сохранить как cp1251 и убедиться, что сервак указывает верную кодировку в Content-type заголовке отдавая страницы и скрипты. В обоих случаях наверное лучше писать рег просто символами, а не \uHHHH кодами, что бы повысить читабельность.

Автор: Innuendo 2.10.2006, 07:08
Цитата(Sardar @  2.10.2006,  00:02 Найти цитируемый пост)
Что бы избежать всей этой лажи лучше пользовать UTF-8. Либо всё сохранить как cp1251 и убедиться, что сервак указывает верную кодировку в Content-type заголовке отдавая страницы и скрипты. В обоих случаях наверное лучше писать рег просто символами, а не \uHHHH кодами, что бы повысить читабельность. 

просто символами не могу - xul расширение не допускает просто киррилицу в яваскрипте... (если я сам её ввёл в исходнике)
а кодировка на сайте, котором это делается стоит в content-type: windows 1251

Автор: Sardar 4.10.2006, 19:57
Цитата(Innuendo @  2.10.2006,  06:08 Найти цитируемый пост)
xul расширение не допускает просто киррилицу в яваскрипте...

Допускает если кодировка исходника может перегнать сие в юникод. Естественно если у тебя в декларации xml лежит UTF-8, а сам сорец в CP1251 или сервер указывает кодировку отдавая файл отличную то реальной, то будет лажа.

Писать же всё \uHHHH конечно будет работать в любом случае хорошо, но исходник не читабелен, что ИМХО большой минус.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)