【问题标题】:word boundaries of UTF-8 text in perlperl 中 UTF-8 文本的字边界
【发布时间】:2011-08-23 09:29:14
【问题描述】:

我的 perl 脚本带有一串 UTF-8 字符,可以是任何语言。我需要将每个单词的第一个字符大写,并将单词的剩余字符转换为小写。这必须在将文本保留为 UTF-8 格式时完成。

当文本仅包含拉丁字符时,以下似乎工作得很好

$my_string =~ s/([\w']+)/\u\L$1/g;

我怎样才能让它在 UTF-8 字符串中工作?

【问题讨论】:

  • Perl 没有 UTF-8 字符串。它有以 Unicode 为单位的字符串,也有以字节为单位的字节字符串。您在那里编写的内容在当前版本的 Perl 中已经可以正常工作。您可能需要像 use v5.12use v5.14use feature "unicode_strings" 这样的东西在编译单元的顶部才能使其工作,但您不需要其他任何东西。
  • 谢谢。我忘了提到我正在使用的网络服务器仍然有 5.8 perl,所以很遗憾我没有这些建议。

标签: regex perl utf-8


【解决方案1】:

请参阅perlunicode,了解您需要熟悉的设施的概述。基本上,您正在寻找类似\p{LC} 的东西。

不过,您的问题空间没有明确定义;并非所有脚本都有字符大小写的概念。 LC 属性只会在匹配的脚本上匹配,所以它应该能让你到达那里。

【讨论】:

  • ...虽然 \w 更接近的替代品可能是 \p{Word}
  • 顺便提一下,"\u\L$1" 中的 \u 和 \L 是否总是正确转换为大小写,或者是否有 unicode 替换这些?
  • 如果您的 Perl 足够新,我相信他们应该使用 DTRT。
  • 实际上,如果你有一个字节字符串而不是字符串,像\p{LC} 这样的东西仍然不起作用。此外,OP 中提供的解决方案在 5.14 中已经运行良好;在编译单元的顶部写use v5.14,一切都会好起来的。我自己从不打扰[\p{CWL}\p{CWT}\p{CWU}]
  • @Appleton:你的问题的答案是功能是正确的,但算法是错误的。在转换为大写字母之前,您不得转换为小写字母,因为如果这样做,您可能会得到某些代码点的错误答案。永远不要写s/(\w+)/\u\L$1/g,因为它只适用于 ASCII。为了保证在 Unicode 上正常工作,您必须编写 s/(\w)(\w*)/\u$1\L$2/g。看到不同?对大小写映射没有往返保证,在大小写映射中也没有任何传递相等性的保证。事实上,我可以找到这样的代码点成立。
猜你喜欢
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 2013-06-17
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
相关资源
最近更新 更多