如何在Clojure正则表达式中使用unicode(UTF-8)字符?

时间:2010-06-23 11:48:22

标签: emacs unicode utf-8 clojure slime

对于你来说,这是一个非常棒的Stacked Overflow Wizards的双重问题。

  1. 如何在与Clojure交谈时将emacs / slime / swank设置为使用UTF-8,或者在命令行REPL中使用UTF-8?目前我无法向swank-clojure发送任何非罗马字符,并且使用命令行REPL会使事情变得糟透了。

  2. 在拉丁文本上进行正则表达式非常简单:

    (re-seq#“[\ w] +”“日语句子真的不需要空格吗?”)

  3. 但如果我有一些日本人怎么办?我认为这会奏效,但我无法测试它:

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

    如果我们必须使用字典来查找单词分隔符,或者自己找到一个只有片假名的单词,那就更难了:

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

    谢谢!

5 个答案:

答案 0 :(得分:15)

对于swank或Emacs无能为力,我很害怕。我在NetBeans上使用Enclojure,它在那里运行良好。

关于匹配:正如亚历克斯所说,\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]+代替没有区别,与日语相同。

但请参阅this regex reference\p{L}匹配Letter类别中的任何Unicode字符,因此它实际上适用于挪威语

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

以及日本人(至少我想是这样,我看不懂它,但似乎是在球场):

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

还有很多其他选项,比如组合变音符号和诸如此类的匹配,请查看参考文献。

编辑:有关Java中的Unicode的更多信息

使用Unicode时对其他潜在兴趣点的快速参考。

幸运的是,Java通常能够以正确的位置和平台编码方式读取和编写文本,但有时您需要覆盖它。

这都是Java,大部分内容都没有Clojure包装器(至少还没有)。

Java字符/字符串在内部是UTF-16。 char类型(及其包装字符)是16位,这不足以表示所有Unicode,因此许多非拉丁文脚本需要两个字符来表示一个符号。

在处理非拉丁语Unicode时,通常最好使用code points而不是字符。代码点是一个表示为int的Unicode字符/符号。 String和Character类具有在Java字符和Unicode代码点之间进行转换的方法。

我把它放在这里,因为我偶尔会需要这些东西,但实际上并不经常记住从一次到下一次的细节。对我未来的自我的一个注释,对于其他开始使用国际语言和编码的人来说也许是有用的。

答案 1 :(得分:8)

答案 2 :(得分:3)

对于片假名,Wikipedia显示Unicode排序。因此,如果您想使用捕获所有片假名的正则表达式字符类,我想您可以这样做:

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

平假名,因为它值得:

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

如果任何正则表达式能够检测到日语单词中断,我会非常惊讶。

答案 3 :(得分:2)

对于国际字符,您需要使用Java Character类,类似于[\ p {javaLowerCase} \ p {javaUpperCase}] +来匹配任何单词字符... \ w用于ASCII - 请参阅java.util.Regex文档

答案 4 :(得分:1)

使用(?U)为您的正则表达式加上前缀:(re-matches #"(?U)\w+" "ñé2_hi") => "ñé2_hi"

这会将UNICODE_CHARACTER_CLASS标志设置为true,以便典型的字符类可以使用非ASCII Unicode执行所需的操作。

有关详细信息,请参阅此处:http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html#UNICODE_CHARACTER_CLASS