【问题标题】:Unicode-aware word-boundary in perlperl 中的 Unicode 感知字边界
【发布时间】:2017-12-19 15:54:04
【问题描述】:

我在 perl-5.24 上,偶然发现 \b 不知道 unicode:

$ echo '""test"" ""тест""' | perl -pe 's/""\b/“/g'
“test"" ""тест""

如我所料,“test"" “тест""

然后我了解了 perl-5.22.1 正则表达式中的 unicode 扩展,特别是这个:\b{wb}。但是使用这些扩展我仍然得到错误的结果:

$ echo '""test"" ""тест""' | perl -pe 's/""\b{wb}/“/g'
“test“ “тест“

正如我预期的那样,“test"" “тест""

我的问题是:我应该通过 perl 正则表达式将 ""test"" ""тест"" 转换为 “test"" “тест"" 吗?

【问题讨论】:

  • @ikegami:是的,我正在通过 UTF-8。但现在世界不是主要是 UTF-8 吗?
  • 不,世界使用解码的文本(String 而不是 byte[]Readers 而不是 Streams 等)。这样,它们与编码无关,而且它们可以更简单,因为它们不担心字符的编码宽度。

标签: regex perl unicode


【解决方案1】:

您告诉s/// 匹配以下内容:

22.22.74.65.73.74.22.22.20.22.22.D1.82.D0.B5.D1.81.D1.82.22.22.A

s///(或更具体地说,\b)需要 Unicode 代码点,因此这意味着将上述内容视为

""test"" ""Ñ<82>еÑ<81>Ñ<82>""

这显然不是你想要的字符串。


同样,您声称您的代码包含以下内容:

s/""\b/“/g

Perl 期望脚本使用 ASCII 编码,除非您使用 UTF-8 对脚本进行编码并添加 use utf8; 以告知它。


解码输入。编码输出。

$ echo '""test"" ""тест""' | perl -pe'
    use utf8;
    use open ":std", ":encoding(UTF-8)";
    s/""\b/“/g
'
“test"" “тест""

$ echo '""test"" ""тест""' | perl -CSDA -Mutf8 -pe's/""\b/“/g'
“test"" “тест""

【讨论】:

  • 从技术上讲,Ñ 也是一个 \w 字符,所以 \b 应该匹配,但这不是因为 Perl 中的一个错误,该错误已通过添加 use feature qw( unicode_strings ); 或 @987654334 修复@。我没有提到这一点,因为一旦我们以正确的方式解决了您的问题,Perl 中的这个错误就会变得毫无意义。
  • 谢谢。我想从今天起我会使用-CSDA -Mutf8
猜你喜欢
  • 2010-12-05
  • 2013-10-04
  • 2017-08-29
  • 2021-05-19
  • 1970-01-01
  • 2017-01-01
  • 1970-01-01
  • 2013-10-04
相关资源
最近更新 更多