Подтвердить что ты не робот

Как использовать символы Unicode (UTF-8) в регулярных выражениях Clojure?

Это двойной вопрос для вас, удивительно добрый Stacked Overflow Wizards.

  • Как установить emacs/slime/swank для использования UTF-8 при разговоре с Clojure или использовать UTF-8 в командной строке REPL? На данный момент я не могу отправить никаких неязыковых символов в swank- clojure, а использование командной строки REPL искажает вещи.

  • Очень легко сделать регулярные выражения по латинскому тексту:

    (re-seq # "[\ w] +" "Действительно верно, что японские предложения не нужны пробелы?" )

Но что, если у меня есть японцы? Я думал, что это сработает, но я не могу проверить это:

(re-seq #"[(?u)\w]+" "日本語 の 文章 に は スペース が 必要 ない って、 本当?")

Нам становится тяжелее, если нам нужно использовать словарь, чтобы найти сломанные перерывы, или найти сами катакана:

(re-seq #"[アイウエオ-ン]" "日本語の文章にはスペースが必要ないって、本当?")

Спасибо!

4b9b3361

Ответ 1

Не могу помочь с шиком или Emacs, боюсь. Я использую Enclojure на NetBeans, и он хорошо работает там.

При совпадении: как сказал Алекс, \w не работает для неанглийских символов, даже расширенные латинские кодировки для Западной Европы:

(re-seq #"\w+" "prøve")  =>("pr" "ve")   ; Norwegian
(re-seq #"\w+" "mañana") => ("ma" "ana") ; Spanish
(re-seq #"\w+" "große")  => ("gro" "e")  ; German
(re-seq #"\w+" "plaît")  => ("pla" "t")  ; French

\ w пропускает расширенные символы. Использование [(?u)\w]+ вместо этого не имеет значения, то же самое с японским.

Но см. эта ссылка для regex: \p{L} соответствует любому символу Юникода в категории Letter, поэтому он действительно работает для норвежского

(re-seq #"\p{L}+" "prøve")
=> ("prøve")

а также для японцев (по крайней мере, я полагаю, что я не могу его прочитать, но, похоже, это в шаге):

(re-seq #"\p{L}+" "日本語 の 文章 に は スペース が 必要 ない って、 本当?")
=> ("日本語" "の" "文章" "に" "は" "スペース" "が" "必要" "ない" "って" "本当")

Есть много других опций, таких как совпадение при объединении диакритических знаков и еще чего-то, проверьте ссылку.

Изменить: больше в Юникоде в Java

Краткая ссылка на другие точки, представляющие потенциальный интерес при работе с Unicode.

К счастью, Java, как правило, очень хорошо читает и пишет текст в правильных кодировках для местоположения и платформы, но иногда вам нужно переопределить его.

Это все Java, большинство из этого материала не имеет обертки Clojure (по крайней мере, пока).

  • java.nio.charset.Charset - представляет собой кодировку, такую ​​как US-ASCII, ISO-8859-1, UTF-8
  • java.io.InputStreamReader - позволяет указать кодировку для перевода из байтов в строки при чтении. Существует соответствующий OutputStreamWriter.
  • java.lang.String - позволяет указать кодировку при создании строки из массива байтов.
  • java.lang.Character - имеет методы для получения категории символов Unicode и преобразования между символами Java и кодами Unicode.
  • java.util.regex.Pattern - спецификация шаблонов регулярных выражений, включая блоки и категории Unicode.

Символы/строки Java являются внутренними UTF-16. Тип char (и его символ-оболочка) составляет 16 бит, что недостаточно для представления всего Юникода, поэтому для многих нелатинских скриптов требуется два символа для обозначения одного символа.

При работе с нелатинским Unicode часто лучше использовать code points, а не символы. Кодовая точка - это один символ/символ Юникода, представленный как int. Классы String и Character имеют методы преобразования символов Java и кодов Unicode.

  • unicode.org - стандартные и кодовые диаграммы Unicode.

Я помещаю это здесь, так как мне иногда нужно это, но не часто достаточно, чтобы фактически запомнить детали из одного раза в другое. Образец примечания к моему будущему "я", и это может быть полезно для других, начинающих работу с международными языками и кодировками.

Ответ 2

Я отвечу на половину вопроса здесь:

Как настроить emacs/slime/swank на использование UTF-8 при разговоре с Clojure или использовать UTF-8 в командной строке REPL?

Более интерактивный способ:

  • M-x customize-group
  • "slime- lisp"
  • Найдите вариант для системы кодирования слизи и выберите utf-8-unix. Сохраните это, чтобы Emacs выбрал его на следующей сессии.

Или поместите это в свои .emacs:

(custom-set-variables '(slime-net-coding-system (quote utf-8-unix)))

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

Работает над Emacs 23 и работает на моей машине

Ответ 3

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

user> (re-seq #"[\u30a0-\u30ff]+" "日本語の文章にはスペースが必要ないって、本当?")
("スペース")

Хирагана, за что стоит:

user> (re-seq #"[\u3040-\u309f]+" "日本語の文章にはスペースが必要ないって、本当?")
("の" "には" "が" "ないって")

Я был бы поражен, если какое-либо регулярное выражение могло бы обнаружить японские разрывы слов.

Ответ 4

для международных символов вам нужно использовать классы Java Character, что-то вроде [\ p {javaLowerCase}\p {javaUpperCase}] + для соответствия любому символу слова... \w используется для ASCII - см. java.util.Regex документация

Ответ 5

Префикс регулярного выражения (?U) следующим образом: (re-matches #"(?U)\w+" "ñé2_hi") => "ñé2_hi".

Устанавливает флаг UNICODE_CHARACTER_CLASS в true, чтобы типичные классы символов выполняли то, что вы хотите, с Unicode без ASCII.

См. здесь для получения дополнительной информации: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS