【问题标题】:Perl | Print ASCII, but backslashed other珀尔 |打印 ASCII,但反斜杠其他
【发布时间】:2017-06-02 15:49:43
【问题描述】:

我希望打印 95 个 ASCII 符号不变,但让其他人打印其代码。 如何在纯perl中制作它? “解包”功能?任何模块?

print BackSlashed('test folder'); # expected test\040folder

print BackSlashed('test тестовая folder'); 
# expected test\040\321\202\320\265\321\201\321\202\320\276\320\262\320\260\321\217\040folder

print BackSlashed('НОВАЯ ПАПКА');
# expected \320\235\320\236\320\222\320\220\320\257\040\320\237\320\220\320\237\320\232\320\220

sub BackSlashed() {
my $str = shift;
.. backslashed code here...
return $str
}

【问题讨论】:

  • 请注意,您是在告诉 Perl 您的子 BackSlashed 没有参数。 sub BackSlashed() 中的括号 () 是一个原型定义,表示它不应该有 args。由于这不是您想要的,请删除括号。

标签: perl ascii utf


【解决方案1】:

您可以将正则表达式替换与已评估的替换部分一起使用。在那里,需要先convert each character to its numeric value,然后output it in octal notation。有一个很好的解释in this answer。附加转义的反斜杠 \ 以使其显示在输出中。

$str =~ s/([^a-zA-Z0-9])/sprintf "\\%03o", ord($1)/eg;

我将捕获组限制为基本的 ASCII 字母和数字。如果你想要其他东西,只需更改角色组即可。


由于您的示例输出包含八位字节,但您说您的代码具有 use utf8 杂注,您需要在运行替换之前将 Perl 的字符串表示转换为相应的八位字节序列。

use utf8;
my $str = 'НОВАЯ ПАПКА';
print foo($str);

sub foo { # note that there are no () here!
    my $str = shift;
    utf8::encode($str);
    $str =~ s/([^a-zA-Z0-9])/sprintf "\\%03o", ord($1)/eg;
    return $str;
}

【讨论】:

  • my $str='НОВАЯ ПАПКА'; $str =~ s/([^a-zA-Z0-9])/sprintf "\\%03o", ord($1)/eg; print $str; #output is: \2035\2036\2022\2020\2057\040\2037\2020\2037\2032\2020
  • 我成功了use utf8; my $str='НОВАЯ ПАПКА'; utf8::encode($str); $str =~ s/([^a-zA-Z0-9])/sprintf "\\%o", ord($1)/eg; print $str;
  • 代码点不是那么高(不要忘记值是八进制的)。例如\2035 给出十六进制的41D(即U+041D/Н/CYRILLIC CAPITAL LETTER EN 的代码点)
  • ASCII 有 128 个字符。 [^\P{ASCII}\P{Print}] 可能只匹配 OP 提到的“95 个 ASCII 字符”。但这并不能根据需要逃脱\ ,所以[^\P{ASCII}\P{Print}\\] 会更好。他们可能还希望对空格进行转义,可以按如下方式完成:[^\P{ASCII}\P{Print}\\ ]
  • 是的,缺少ord。不,这只是一句随意的评论:UTF-8 以外的编码需要更加小心。
猜你喜欢
  • 2019-05-05
  • 1970-01-01
  • 2019-01-13
  • 2013-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多