perl 和 UTF-8 的问题

perl 和 UTF-8 的问题

如果我正确解释文档 ci=orrectly,perl --CSD则应该确保输入和输出、处理或命令都使用 UTF-8 编码。

但是,如果我将两个连字符替换--为一个破折号 — (U+2014),则结果不会在 MacOS 12.1 中的 UTF-8 语言环境中呈现为破折号(我没有其他操作系统可以尝试)。

为了避免在上传、服务器和客户端渲染之间出现进一步的编码/渲染问题,我展示了屏幕截图而不是粘贴文本:

在此处输入图片描述

如果我在假定 UTF-8 输入的编辑器中打开文件,它会显示相同的内容。如果我使用该编辑器添加另一个破折号,则第二个破折号会正确呈现,并且编码肯定不同:

WGroleau@MBP ~ % od -xc /tmp/demo.txt 
0000000      2049    6177    746e    6120    206e    6d65    642d    7361
           I       w   a   n   t       a   n       e   m   -   d   a   s
0000020      2068    6562    7774    6565    206e    6874    7365    3a65
           h       b   e   t   w   e   e   n       t   h   e   s   e   :
0000040      4a20    656f    a2c3    80c2    94c2    6f54    0a6d    2049
               J   o   e   â  ** 302 200 302 224   T   o   m  \n   I    
0000060      6177    746e    6120    206e    6d65    642d    7361    2068
           w   a   n   t       a   n       e   m   -   d   a   s   h    
0000100      6562    7774    6565    206e    6874    7365    3a65    4a20
           b   e   t   w   e   e   n       t   h   e   s   e   :       J
0000120      656f    80e2    5494    6d6f    0a0a                        
           o   e   —  **  **   T   o   m  \n  \n                        

是存在错误,还是我做错了什么?我需要在许多文件中自动执行多个替换,并且它们包含多种语言,因此非 ASCI 字符可能在搜索端和替换端。

更新:我确实可以访问 Debian 系统,但是是通过 ssh 访问的。我看到“perl 5,版本 28,subversion 1 (v5.28.1) 为 x86_64-linux-gnu-thread-multi 构建(带有 65 个注册补丁...”)”也出现同样的情况,但由于我是远程连接的,因此我的系统仍在呈现它。

我的 perl 是“为 darwin-thread-multi-2level 构建的 perl 5,版本 34,subversion 0(v5.34.0)”,没有提到补丁。

如果不需要更大的脚本或数小时学习新语言,我愿意使用其他工具来代替 perl。我已经有几种语言可以做到这一点,但没有一种特别方便。

答案1

命令行与标准输入不同,它不经过 PerlIO – 它是一个平面字符串数组(在 Perl 中),由而不是@ARGV处理。您需要涵盖所有内容。-CA-CS-CSDA

(或者,utf8::decode($_) for @ARGV在脚本开头附近调用。)

答案2

从 Tom Yan 的评论来看,-CSD 实际上在某种程度上搞砸了。忽略它,通常¹我就能得到我想要的东西(至少在我的语言环境中是这样):

WGroleau@MBP ~ % echo "Let’s try again for an em-dash" > /tmp/tmp
WGroleau@MBP ~ % cat /tmp/tmp
Let’s try again for an em-dash
WGroleau@MBP ~ % perl -p -i -e 's:em-dash:—:g;' !$
perl -p -i -e 's:em-dash:—:g;' /tmp/tmp
WGroleau@MBP ~ % cat !$
cat /tmp/tmp
Let’s try again for an —
WGroleau@MBP ~ % perl -p -i -e 's:—:--:g;' /tmp/tmp # change it to ASCII
WGroleau@MBP ~ % cat /tmp/tmp
Let’s try again for an --

我觉得这似乎是个 bug,但我真的不知道。正如我提到的,我需要进行其他非 ASCII 替换(当然,首先要进行测试)。

¹除了如果我尝试用 ASCII 替换(U+2019) ',zsh 会抱怨打开引号! Escape\'没有帮助。

相关内容