为什么“\w”不匹配 Perl 正则表达式中的 Unicode 单词字符(例如,“?,?,?,ç,ö,ü”)?

ero*_*gol 5 regex unicode perl

为什么“\w”不匹配 Perl 正则表达式中的 Unicode 单词字符(例如,“?,?,?,ç,ö,ü”)?

我试图在正则表达式中包含这些字符m{\w+}g。但是,它不匹配“?,?,?,ç,ö,ü”。

我怎样才能使这项工作?

use strict;
use warnings;
use v5.12;
use utf8;

open(MYINPUTFILE, "< $ARGV[0]");

my @strings;
my $delimiter;
my $extensions;
my $id;

while(<MYINPUTFILE>)
{
    my($line) = $_;
    chomp($line);
    print $line."\n";
    unshift(@strings,$line =~ /\w+/g);
    $delimiter = /[._\s]/;
    $extensions = /pdf$|doc$|docx$/;
    $id = /^200|^201/;
}

foreach(@strings){
    print $_."\n";
}
Run Code Online (Sandbox Code Playgroud)

输入文件是这样的:

Çidem_?
ener Hüsnü Ta?lip
...

输出如下:

H?

sn?

Ta?

lip

?

idem_?

ener
Run Code Online (Sandbox Code Playgroud)

在代码中,我尝试读取文件并获取数组中的每个字符串。(分隔符可以是_.\s)。

小智 1

Unicode 可能是一个挑战,而 Perl 有其自身的特点。\n基本上,Perl 在所有与 Unicode 有关的输入/输出途径周围设置了防火墙。你必须告诉 Perl I/O 的路径是否有编码。如果是,则规则对于任何输入都是解码,和/或对于任何输出都是编码。

\n\n

解码将数据从 {encoding} 转换为 Perl 使用的内部表示,这可能是字节和代码点的组合。

\n\n

编码输出的作用恰恰相反。

\n\n

因此,实际上可以“解码输入”和“编码输出”为两种不同的编码。你只需要告诉它它是什么。编码/解码通常通过文件 I/O 层完成,但您可以使用 Encode 模块(发行版的一部分)在编码之间手动来回转换。

\n\n

不过关于 Unicode 的 perldocs读起来并不轻松。

\n\n

这是一个可能有助于可视化它的示例(还有许多其他方法)。

\n\n
use strict;\nuse warnings;\nuse Encode;\n\n\n# This is an internalized string with these UTF-8 codepoints\n# ----------------------------------------------\nmy $internal_string_1 = "\\x{C7}\\x{69}\\x{64}\\x{65}\\x{6D}\\x{5F}\\x{15E}\\x{65}\\x{6E}\\x{65}\\x{72}\\x{20}\\x{48}\\x{FC}\\x{73}\\x{6E}\\x{FC}\\x{20}\\x{54}\\x{61}\\x{11F}\\x{6C}\\x{69}\\x{70}";\n\n\n# Open a temp file for writing as UTF-8.\n# Output to this file will be automatically encoded from Perl internal to UTF-8 octets.\n# Write the internal string.\n# Check the file with a UTF-8 editor.\n# ----------------------------------------------\nopen (my $out, \'>:utf8\', \'temp.txt\') or die "can\'t open temp.txt for writing $!";\nprint $out $internal_string_1;\nclose $out;\n\n\n# Open the temp file for readin as UTF-8.\n# All input from this file will be automatically decoded as UTF-8 octets to Perl internal.\n# Read/decode to a different internal string.\n# ----------------------------------------------\nopen (my $in, \'<:utf8\', \'temp.txt\') or die "can\'t open temp.txt for reading $!";\n$/ = undef;\nmy $internal_string_2 = <$in>;\nclose $in;\n\n\n# Change the binmode of STDOUT to UTF-8.\n# Output to STDOUT will now be automatically encoded from Perl internal to UTF-8 octets.\n# Capture STDOUT to a file then check with a UTF-8 editor.\n# ----------------------------------------------\nbinmode STDOUT, \':utf8\';\nprint $internal_string_2, "\\n\\n";\n\n\n# Use encode() to convert an internal string to UTF-8 octets\n# Format the UTF-8 octets to hex values\n# Print to STDOUT\n# ----------------------------------------------\nmy $octets = encode ("utf8", $internal_string_2);\nprint "Encoded (out) string -> UTF-8 (octets):\\n";\nprint "   length  =  ".length($octets)."\\n";\nprint "   octets  =  $octets\\n";\nprint "   HEX val =  ";\nfor (split //, $octets) {\n    printf ("0x%X ", ord($_));\n}\nprint "\\n\\n";\n\n\n# Use decode() to convert external UTF-8 octets to an internal string.\n# Format the internal string to codepoints (hex values).\n# Print to STDOUT.\n# ----------------------------------------------\nmy $internal_string_3 = decode ("utf8", $octets);\nprint "Decoded (in) string <- UTF-8 (octets):\\n";\nprint "   length      =  ".length($internal_string_3)."\\n";\nprint "   string      =  $internal_string_3\\n";\nprint "   code points =  ";\nfor (split //, $internal_string_3) {\n    printf ("\\\\x{%X} ", ord($_));\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

输出

\n\n
\xc3\x87idem_\xc5\x9eener H\xc3\xbcsn\xc3\xbc Ta\xc4\x9flip\n\nEncoded (out) string -> UTF-8 (octets):\n   length  =  29\n   octets  =  \xc3\x83idem_\xc3\x85ener H\xc3\x83\xc2\xbcsn\xc3\x83\xc2\xbc Ta\xc3\x84lip\n   HEX val =  0xC3 0x87 0x69 0x64 0x65 0x6D 0x5F 0xC5 0x9E 0x65 0x6E 0x65 0x72 0x20 0x48 0xC3 0xBC 0x73 0x6E 0xC3 0xBC 0x20 0x54 0x61 0xC4 0x9F 0x6C 0x69 0x70\n\nDecoded (in) string <- UTF-8 (octets):\n   length      =  24\n   string      =  \xc3\x87idem_\xc5\x9eener H\xc3\xbcsn\xc3\xbc Ta\xc4\x9flip\n   code points =  \\x{C7} \\x{69} \\x{64} \\x{65} \\x{6D} \\x{5F} \\x{15E} \\x{65} \\x{6E} \\x{65} \\x{72} \\x{20} \\x{48} \\x{FC} \\x{73} \\x{6E} \\x{FC} \\x{20} \\x{54} \\x{61} \\x{11F} \\x{6C} \\x{69} \\x{70}\n
Run Code Online (Sandbox Code Playgroud)\n