首页 > 解决方案 > Perl - 在 cp1251 中复制到剪贴板

问题描述

试图复制到 cp1251 中的剪贴板文本。

#!/usr/bin/perl -w

use Clipboard;
use Encode;

    my $ClipboardOut = "A bunch of cyrillic characters - а-б-в-г \n";
    Encode::from_to($ClipboardOut, 'utf-8', 'cp1251');

    Clipboard->copy($ClipboardOut);

而不是西里尔字母“?” 粘贴在任何 Windows 应用程序中。如果我删除带有编码的行 - 西里尔字母会产生带有不同修饰符的“a'-s:

A bunch of cyrillic characters   à-á-â-ã 

我想我错过了一些非常简单的东西,但我坚持下去了。有人可以帮我吗?

标签: perlclipboardcp1251

解决方案


在 Windows 中,剪贴板需要使用系统的活动代码页编码的文本。那是因为 Clipboard 只是Win32::Clipboard的包装器。虽然 Win32::Clipboard 允许您从剪贴板接收任意 Unicode 文本,但它不允许您在剪贴板上放置任意 Unicode 文本。因此,直接使用该模块无济于事。

这是限制性的。例如,我机器的 ACP 是cp1252,所以我不能使用这个模块在剪贴板上放置西里尔字符。

假设您系统的 ACP 支持有问题的西里尔字符,这里有两种解决方案:(我直接使用 Win32::Clipboard,但您可以使用相同的方式使用 Clipboard。)


使用 UTF-8 编码的源代码(这通常是理想的)

use utf8;

use Encode           qw( encode );
use Win32            qw( );
use Win32::Clipboard qw( );

# String of decoded text aka Unicode Code Points because of `use utf8;`
my $text_ucp = "а-б-в-г\n";

my $acp = "cp" . Win32::GetACP();
my $clip = Win32::Clipboard();
$clip->Set(encode($acp, $text_ucp));

根据活动代码页编码的源代码

Perl 期望源代码使用 ASCII(no utf8;默认值)或 UTF-8(带有use utf8;)编码。但是,字符串和正则表达式no utf8;在生效时是“8 位干净的”(默认值),这意味着任何与 ASCII 字符不对应的字节都将生成与该字节具有相同值的字符。

use Win32::Clipboard qw( );

# Text encoded using source's encoding (because of lack of `use utf8`),
# which is expected to be the Active Code Page.
my $text_acp = "а-б-в-г\n";

my $clip = Win32::Clipboard();
$clip->Set($text_acp);

推荐阅读