【问题标题】:What's wrong with \W on non UTF-8 encodings using Scala?使用 Scala 进行非 UTF-8 编码的 \W 有什么问题?
【发布时间】:2015-10-23 01:55:55
【问题描述】:

所以,我正在查看 Typesafe Activator 教程和it says 使用的正则表达式; 类似的非字母数字替代\W+,效果不佳 使用非 UTF8 字符集!

这似乎是一件很奇怪的事情。

原评论全文:

// Split on non-alphabetic sequences of characters. Note the regex used;
// the similar, non-alphanumeric alternative """\W+""", does not work well
// with non-UTF8 character sets!

以及后面的代码:

val wc = input
    .flatMap(line => line.split("""[^\p{IsAlphabetic}]+"""))
    .map(word => (word, 1))
    .reduceByKey((count1, count2) => count1 + count2)

\W 和非 UTF8 字符集有什么问题?

【问题讨论】:

    标签: regex scala utf-8


    【解决方案1】:

    评论对我来说没有意义。

    但是,\w 默认情况下确实只识别 ASCII 范围 [A-Za-z0-9_] 中的单词字符,这意味着补码字符集 \W 考虑了 Unicode 的其余部分(包括来自各种语言的字母)作为非单词s。

    \p{IsAlphabetic} 是单词字符的更好近似值,因为它包含 Letter 中的字符(Lu、Ll、Lt、Lm、Lo)和 数字、字母 (Nl) category,以及其他一些字母字符。但是,完全没有数字(Nd 类别)和组合标记(Mc 类别)。

    更好的解决方案是使用Pattern.UNICODE_CHARACTER_CLASS 或等效的内联标志(?U),可从Java 7 获得,以使\w、\s 和\d(以及其他预定义的字符类)支持Unicode。

    所以代码的sn-p应该改成

        .flatMap(line => line.split("""(?U)\W+"""))
    

    如果 (?U) 标志在 Java 的特定实现中不可用,则可以使用以下字符类模拟 \w(只需为 \W 取反):

    [\p{IsAlphabetic}\p{M}\p{Nd}\p{Pc}\u200c\u200d]
    

    注意事项:请注意,Unicode 字符类,如 \p{IsAlphabetic}、\p{M} 或 \W(带有 (?U) 标志)对于稍后添加的字符可能会表现出略微不同的行为Unicode 版本,或在 Unicode 版本之间更改类别的字符。它本质上高度依赖于运行代码的系统上的 Unicode 曲目。

    【讨论】:

    • 所以...\W is equivalent to [^\p{AlNum}], according to Oracle's API documentation。投诉不是[^\p{IsAlphabetic}]?所以,问题不在于将\W 与非UTF8 一起使用,而在于通常与Unicode 字符一起使用。
    • @IonFreeman:在 Java 或 Scala 中保存字符串时,没有“非 UTF-8”的概念。 Java/Scala 中的 String 对象始终是 UTF-16 代码单元的数组,从文件中读取的数据(以字节为单位)将被解码,然后编码为 UTF-16 作为 String 对象。至于\p{Alnum},它不等同于\w,因为\w 包括_,但那些POSIX 字符类默认只识别ASCII 字符。另一方面,\p{IsAlphabetic} 检查 Unicode 标准中定义的 Unicode 属性“Alphabetic”。
    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多