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

это двойной вопрос для вас удивительно добрый сложены мастера переполнения там.

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

  2. это действительно легко сделать регулярные выражения на латинском тексте:

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

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

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

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

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

спасибо!

5 ответов


боюсь, не могу помочь с swank или 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} соответствует любому символу Unicode в категория письмо, так что это на самом деле работает для норвежского

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

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

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

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

Edit: подробнее о Unicode в Java

краткая ссылка на другие точки потенциального интереса при работе с Unicode.

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

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

  • java.НИО.кодировка.Charset - представляет кодировку как US-ASCII, ISO-8859-1, UTF-8
  • java.Ио.InputStreamReader - позволяет вы указываете кодировку для перевода из байтов в строки при чтении. Существует соответствующий OutputStreamWriter.
  • java.ленг.Строка - позволяет указать кодировку при создании строки из массива байт.
  • java.ленг.Характер - имеет методы для получения категории Unicode символа и преобразования между символами Java и кодовыми точками Unicode.
  • java.утиль.регулярное выражение.Шаблон - спецификация шаблонов регулярных выражений, включая блоки и категории Unicode.

символы/строки Java являются UTF-16 внутренне. The char type (и его символ-оболочка) составляет 16 бит, что недостаточно для представления всего Unicode, поэтому многим нелатинским скриптам нужны два символа для представления одного символа.

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

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

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


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

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

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

  1. M-x настроить-группа
  2. "слизь-сюсюкать"
  3. найдите опцию для системы кодирования slime и выберите utf-8-unix. Сохраните это, чтобы Emacs взял его в следующем сессия.

или поместите это в ваш .в Emacs:

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

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

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


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

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

Хирагана, для чего это стоит:

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

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


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


префикс вашего regex с (?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