【问题标题】:Perl regex replace with UTF-8 charactersPerl 正则表达式替换为 UTF-8 字符
【发布时间】:2014-02-01 06:23:06
【问题描述】:

我对尝试使用Perl 编写的函数感到绝望。我的功能是过滤特定字符的字符串。我允许一些字符,如A-Z, a-z, 0-9,我还希望允许一些德语变音符号。但是每次我在正则表达式中定义它们时,替换都会失败。

我的编码是UTF-8(服务器、perl、脚本)。

这是我的功能:

sub cleanXSS{

    my $string = shift;

    $string =~ s/[^A-Za-z0-9öäü]//g;

    return $string;
}

我的脚本如下所示:

my $scalar = "áéíóúÁÉÍüÓÚâêÄîôßû()ÂÊÎÔÛabcäüöÄÜÖý#µzdjheäöü";
print cleanXSS($scalar)."\n";

所以它应该替换除A-Z, a-z, 0-9 和小写变音符号之外的所有字符。在我的测试字符串中替换德语变音符号工作正常,但似乎所有其他拉丁字符仅被部分替换。

控制台输出如下所示:

▒▒▒▒▒▒▒▒▒ü▒▒▒▒▒▒▒▒▒▒▒▒▒▒abcäüö▒▒▒▒zdjheäöü

我尝试了许多解决方案,例如“使用语言环境”、其他编码、通过“使用编码”的显式编码等等。

似乎在á 之类的字符中,仅替换了 2 个字节中的 1 个。如果我将替换更改为:

$string =~ s/[^A-Za-z0-9öäü]/_/g;

我得到以下输出:

▒_▒_▒_▒_▒_ö▒_▒_▒_ü▒_▒_▒_▒_▒_▒_▒_▒_▒___▒_▒_▒_▒_▒_abcäüö▒_▒_▒_▒____zdjheäöü

我怎样才能做到这一点?

【问题讨论】:

  • 确保将文件保存为 UTF8,并使用 use utf8;(或 BOM)。

标签: regex perl utf-8 character-encoding diacritics


【解决方案1】:

似乎在像“á”这样的字符中,仅替换了 2 个字节中的 1 个。

  1. 解码输入。

    您没有告诉 Perl 您的脚本是使用 UTF-8 编码的。添加

    use utf8;
    
  2. 编码输出。

    您还需要以下内容来对输出进行编码:

    use open ':std', ':encoding(UTF-8)';
    

【讨论】:

  • 虽然我不太明白为什么,但它确实有效。我已经尝试过“使用 utf8;”和 "binmode STDOUT, ":encoding(UTF-8)";"之前,就像 M42 解释的一样。然后替换工作正常,但所有其他输出的编码错误。只有通过您的第二步,它才能按需要工作。非常感谢!
  • 关于“我不太明白为什么,但它有效”,就 Perl 而言,该文件包含 my $scalar = "áéíó...";,因为您没有告诉它您使用 UTF-8。
  • 怎么会这样。文件的编码是 UTF8。可以肯定的是,我已经用 notepad++ 对其进行了转换。
  • file 可能是 UTF-8,但您没有告诉 Perl。默认情况下,Perl 假定文件是 ISO-8859-1。
  • 某些编码错误相互抵消是很常见的。
【解决方案2】:

将此行放在脚本的开头:

binmode STDOUT, ":encoding(UTF-8)";

doc

【讨论】:

  • 我已经尝试过你的解决方案,这是我的输出:Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã_Ã___Ã_Ã_Ã_Ã_Ã_abcäÃ_Ã_Ã_Ã_Ã_Ã___zdjheäÃ_Ã_
  • 由于 OPs 替换不能正常工作,Perl 对输入字符串和/或替换的某些编码有错误。 (没有这个,当他得到其他 utf8 的东西时,他的输出也会有问题。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多