Рубрики
Без рубрики

Поиск диакритических знаков в таблице Postgres

Недавно у меня была задача найти все диакритические знаки в таблице базы данных. Я должен был найти легкий способ… С тегами postgres, java, база данных.

Недавно у меня была задача найти все диакритические знаки в таблице базы данных. Мне пришлось найти простой способ выбрать каждую строку, в названии которой есть диакритический знак. Решение было на удивление простым, но немного неинтуитивным. В этой статье я предоставлю вам это решение, а также дополнительную информацию о том, как Java и Postgres обрабатывают диакритические знаки и другие символы.

Что такое диакритический знак?

Диакритический знак – это знак или ударение на букве, указывающее, что буква должна произноситься по-другому. Диакритические знаки часто называют ударениями. Отмеченная буква и немаркированная буква логически являются одними и теми же буквами в языке. Примерами диакритических знаков являются

áàâüñçå

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

Æ æ Ø ø Ł ł

При работе с диакритическими знаками важно понимать, как система будет относиться к определенным символам.

Как Java справляется с диакритическими знаками?

Java строго обрабатывает диакритические знаки. Для этих примеров мы будем использовать утилиту Normalizer.normalize в библиотеке Apache Commons-text. Мы увидим, что “Æ æ Ø ø L”, не заменяются аналогичным английским аналогом.

Мы будем использовать следующий метод для тестирования

public static String stripDiacritics(String input){
if ( !Normalizer.isNormalized(input, Normalizer.Form.NFD) ) {
return Normalizer.normalize(input, Normalizer.Form.NFD).replaceAll("\\p{M}+", "");
}
return input;
}

Тестирование этого метода приведет к следующему

 @test

public void testStripDiacritic(){
assertEquals("aabbsser3ssa35ds", DiacriticUtility.stripDiacritics("aabbsser3ssa35ds"));
assertEquals("This is a funky String", DiacriticUtility.stripDiacritics("Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ"));
assertEquals("Ø or Ł", DiacriticUtility.stripDiacritics("Ø or Ł"));
assertEquals("the German umlauts: a, o, u", DiacriticUtility.stripDiacritics("the German umlauts: ä, ö, ü"));
assertEquals("manana", DiacriticUtility.stripDiacritics("mañana"));
assertEquals("Æ æ Æ æ or Æ æ", DiacriticUtility.stripDiacritics("Ǣ ǣ Ǽ ǽ or Æ æ"));
}

Обратите внимание, что диакритические знаки, такие как “ůňķŷ”, заменены на “unky”, но “Æ æ” не заменены на “AE ae”.

Как Postgres обрабатывает диакритические знаки?

Postgres обрабатывает диакритические знаки так же, как Java, но по-другому влияет на другие символы. В Postgres мы используем расширение uncent .

Для установки без учета выполните следующие действия.

CREATE EXTENSION unaccent;

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

select unaccent('Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ | łŁØø | ä, ö, ü | Ǣ ǣ Ǽ ǽ æ or Æ æ') 
FROM blog.diacritic_blog LIMIT1;

Выход:

This is a funky String | lLOo | a, o, u | Ǣ ǣ Ǽ ǽ ae or AE ae

Notice that the expected diacritics are resolved, but so is “? ? l l??”. Достаточно интересно, что отсутствие Постгреса не разрешает “Ǣ ǣ Ǽ ǽ” на “Æ æ Æ” или на “AE ae AE as”.

Поиск диакритических знаков в таблице Postgres?

Как мы видели выше, существует множество особых случаев, касающихся того, как Postgres будет обрабатывать диакритические знаки и специальные символы. Это решение для поиска строк с диакритическими знаками не будет учитывать эти крайние случаи, но даст вам базовое решение для запроса таблицы для диакритических знаков. Вы можете добавить регулярное выражение и дополнительные предложения where в запрос по мере необходимости.

В этом примере будет использоваться следующее

CREATE TABLE blog.diacritic_blog(
id bigserial NOT NULL,
name varchar(255) NOT NULL,
CONSTRAINT pk_diacritic_id PRIMARY KEY (id)
);

INSERT INTO blog.diacritic_blog(name) values ('aabbsser3ssa35ds');
INSERT INTO blog.diacritic_blog(name) values ('Tĥïŝ ĩš â fůňķŷ Šťŕĭńġ');
INSERT INTO blog.diacritic_blog(name) values ('Ø or Ł or łŁØø');
INSERT INTO blog.diacritic_blog(name) values ('the German umlauts: ä, ö, ü');
INSERT INTO blog.diacritic_blog(name) values ('mañana');
INSERT INTO blog.diacritic_blog(name) values ('Ǣ ǣ Ǽ ǽ æ or Æ æ');

Следующий запрос вернет 5 строк:

SELECT name, unaccent(name) FROM blog.diacritic_blog where name != unaccent(name);

выход:

This is a Funky String Это обалденная строка
? Or L or lłøø О или Л или Ллу
the German umlauts: ä, ö, ü немецкие умлауты: а, о, у
утро манана
Выпил выпил Ǽ ǽ æ or Æ Æ Ǣ ǣ Ǽ ǽ аэ или АЭ ae

Резюме

Найти все диакритические знаки в таблице Postgres просто, если не сказать немного неинтуитивно. Однако обработка диакритических знаков и символов неанглийского алфавита – это минное поле. Надеюсь, теперь у вас есть базовое представление о диакритических знаках и о том, как Java и Postgres обрабатывают эти символы.

Если вы хотите увидеть полное описание того, как другие языки (JavaScript или Python) обрабатывают эти символы, пожалуйста, свяжитесь со мной через Twitter @ryboflavin42 и дайте мне знать, какие еще языки вы хотели бы видеть.

Примеры из этой статьи можно найти на GitHub по адресу https://github.com/djchi82/DiacriticBlogProject .

Оригинал: “https://dev.to/ryboflavin42/finding-diacritics-in-a-postgres-table-4kcc”