Как использовать символы Юникода (UTF-8) в регулярных выражениях Clojure? - PullRequest
12 голосов
/ 23 июня 2010

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

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

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

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

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

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

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

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

Спасибо!

Ответы [ 5 ]

15 голосов
/ 23 июня 2010

Боюсь, я не могу помочь с Суонком или 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]+ вместо этого не имеет значения, то же самое с японцами.

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

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

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

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

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

Редактировать: Подробнее о Unicode в 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, поэтому многим нелатинским сценариям нужны два символа для представления одного символа.

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

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

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

8 голосов
/ 23 июля 2010

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

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

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

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

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

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

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

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

3 голосов
/ 23 июня 2010

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

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

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

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

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

2 голосов
/ 23 июня 2010

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

1 голос
/ 02 февраля 2017

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

. Устанавливает для флага UNICODE_CHARACTER_CLASS значение true, чтобы типичные классы символов выполняли то, что вы хотите, с не-ASCII Unicode.1006 * Смотрите здесь для получения дополнительной информации: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS

...