Символы "ي" и "ی" и разница в персидском - Мыскле
Я работаю на персидском веб-сайте UTF-8 со встроенной базой данных mysql. Все содержимое веб-сайта импортируется через панель администратора, и все персидские.
Как вы знаете, арабский язык имеет те же буквы, что и персидский, кроме некоторых.
Проблема заключается в том, что человек пытается ввести на клавиатуре арабский макет, который пишет "ي" в качестве символа, и если он пытается ввести клавиатуру с персидским макетом, он набирает "ی" как символ.
Так что, если человек ищет "بازی", mysql не найдет "بازي" в качестве результата.
Важное примечание: "ی" - не единственный символ с этим свойством, их много, и они очень похожи.
Как я могу исправить эту проблему?
Одно простое наивное решение похоже, заменяет все "ي" на "ی" перед импортом данных в базу данных, но я ищу более надежное решение, чем это.
Ответы
Ответ 1
Дорогой EBAG, у нас есть единственный арабский блок в Unicode, который содержит как арабский, так и персидский символы.
06CC - персидский ی
и 064A - арабский ي
Клавиатура окон по умолчанию использует code page 1256
для арабских символов, которые ставят 064A
по умолчанию ي
для пользователей Persian и Arab, поскольку арабские пользователи намного больше, чем персидские.
ISIRI
создайте стандартную клавиатуру ISIRI 9147
и поместите на нее как арабский, так и персидский Yeh
, но Perisan ی
- это символы по умолчанию. Персидские пользователи, которые используют стандартную клавиатуру, ставят (и используют) стандартный персидский ی while the rest of them use arabic
ي`.
Как вы обычно говорили, когда мы сохраняем данные в базе данных, мы меняем арабский ي
на персидский ی
, и когда мы читаем от него, мы просто переходим к персидскому, чтобы все было правдой.
второй подход заключается в использовании файла JavaScript в веб-приложении для управления вводом пользователя. большинство персидских сайтов используют этот подход для сохранения символов в базе данных. В этом методе пользователю не нужно устанавливать любую раскладку клавиатуры для персидской или арабской клавиатуры. Он/она просто кладет клавиатуру на English
, а затем в JavaScript
разработчик файла проверяет, какой символ эквивалентен для него. Здесь вы можете найти ISIRI 9147 javascript
для веб-приложения и Persian Guid, чтобы использовать его.
Третий подход - использовать экранную клавиатуру, которая работает так же, как и предыдущая, с пользовательским интерфейсом и обычно хороша для этого, кто не знаком с персидской клавиатурой.
Четвертый подход - поиск обоих диалектов. Как вы знаете, когда вы устанавливаете MySql
или SQL Server
, вы можете установить collation
, а также иметь возможность поддерживать диалект (и чувствительность к случаю). если вы включите арабскую сортировку с диалектом, вы можете получить результат для обоих из них, и обычно это отлично работает в SQL Server
. Я не тестирую его в MySql
. Это лучшее решение.
но если бы я был вами, я реализую простой sql function
, который получает nvarchar
и возвращает nvarchar
. то я называю это, когда хочу писать данные. и всякий раз, когда вы хотите читать, вы можете пойти на стандартный.
Извините за длинный хвост.
Ответ 2
update TABLENAME set COLUMNNAME=REPLACE(COLUMNNAME,NCHAR(1610),NCHAR(1740))
или
update TABLENAME set COLUMNNAME=REPLACE(COLUMNNAME,'ي',N'ی')
Ответ 3
Это называется сортировкой. Это то, что MySQL использует для сравнения двух разных символов. Боюсь, я ничего не знаю о персидском или арабском, но концепция такая же. По существу у вас есть два символа, которые сопоставляются с одним и тем же базовым значением. Вам нужно найти сопоставление, которое отображает ي на ی. Я боюсь, что это так полезно, как я могу быть, не зная больше о языке.
Ответ 4
Первая буква (ي) есть Yā' в арабском алфавите.
Вторая буква (ی) - это вы в перу-арабском алфавите.
Подробнее о персо-арабском алфавите:
http://en.wikipedia.org/wiki/Perso-Arabic_alphabet
"Две точки удаляются в финале ye (ی). Арабский язык отличает заключительную yā'у двумя точками и alif maqsura (кроме египетского арабского), который написан как окончательный yā' без двух точек.
Потому что персидский бросает две точки в финале вы, alif maqsura нельзя отличить от нормального финала ye. Например, имя Муса (Моисей) написано موسی. В последнем письме в Мусе персидский язык не различает вас или алифа максура.
Кажется, это интересная проблема...
Ответ 5
Я боролся с подобной ситуацией 5-6 лет назад, когда Lucene не был вариантом для MySQL и не было Sphinx (никогда не пробовал результат Sphinx на этом), но то, что я сделал, я нашел в значительной степени большую часть возможные чередования и помещать их в массив в PHP.
Поэтому, если ключевое слово ввода содержало любой из этих символов, я сгенерировал все возможные альтернативы этого.
Итак, для ввода 'بازی' я бы сгенерировал {'بازي', 'بازی'}, а затем я бы запросил MySQL для обоих, как простейший запрос ниже:
SELECT title,Describtion FROM Games WHERE Description LIKE '%بازي%' OR Description LIKE '%بازی%'
Основной список альтернатив не очень длинный.
Ответ 6
Если у вас есть возможность переключить механизм БД, вы можете посмотреть в функции полнотекстового поиска PostgreSQL:
http://www.postgresql.org/docs/9.0/static/textsearch.html
Кроме всего прочего, вы можете настроить его так, чтобы он индексировал/искал безрезультатные символы, и вы можете определить всевозможные дополнительные словари (например, стоп-слова, тезаурус, синонимы и т.д.).
Если нет, рассмотрите возможность использования Sphinx или Lucene вместо like
для ваших поисков.
Ответ 7
Я знаю, что отвечать на эту тему - это как выкапывать труп из его могилы, так как он действительно старый, но я хотел бы поделиться своим опытом ИМХО, лучший способ - обернуть свой запрос и применить свою замену. он более портативный, чем другие способы. здесь представлен образец Java
public class FarsiRequestWrapper extends HttpServletRequestWrapper{
@Override
public String getParameter(String name) {
String parameterValue = super.getParameter(name);
parameterValue.replace("ی", "ي");
parameterValue.replace("\\s+", " ");
parameterValue.replace("ک","ک");
return parameter.trim();
}
}
вам нужно только установить сервлет фильтра
public class FarsiFilter implements Filter{
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
FarsiRequestWrapper rw = new FarsiRequestWrapper(req);
chain.doFilter(rw, response);
}
}
хотя этот подход работает только на Java, я нашел его проще и лучше.
Ответ 8
Вы должны использовать N (то есть uNicode) перед неанглийскими символами, например:
REPLACE(COLUMNNAME, N'ي', N'ی')