8

我正在尝试用单引号或双引号替换各种字符。

这是我的测试文件:

# Replace all with double quotes
" fullwidth
“ left
” right
„ low
" normal

# Replace all with single quotes
' normal
‘ left
’ right
‚ low
‛ reverse
` backtick

我正在尝试这样做...

perl -Mutf8 -pi -e "s/[\x{2018}\x{201A}\x{201B}\x{FF07}\x{2019}\x{60}]/'/ug" test.txt
perl -Mutf8 -pi -e 's/[\x{FF02}\x{201C}\x{201D}\x{201E}]/"/ug' text.txt

但只有反引号字符被正确替换。我认为这与其他代码点太大有关,但我找不到任何关于此的文档。

在这里,我有一个转储 Unicode 代码点的单行代码,以验证它们是否与我的正则表达式匹配。

$ awk -F\  '{print $1}' test.txt | \
    perl -C7 -ne 'for(split(//)){print sprintf("U+%04X", ord)." ".$_."\n"}'

U+FF02 "
U+201C “
U+201D ”
U+201E „
U+0022 "

U+0027 '
U+2018 ‘
U+2019 ’
U+201A ‚
U+201B ‛
U+0060 `

为什么我的正则表达式不匹配?

4

2 回答 2

22

它不匹配,因为您忘记了-CSAD 对 Perl 的调用,并且没有$PERL_UNICODE在您的环境中设置。您只是说-Mutf8要宣布您的源代码采用该编码。这不会影响您的 I/O。

你需要:

$ perl -CSAD -pi.orig -e "s/[\x{2018}\x{201A}\x{201B}\x{FF07}\x{2019}\x{60}]/'/g" test.txt

我确实在这个答案中提到过这种事情几次。

于 2012-10-01T20:49:19.560 回答
8

使用use utf8;,您告诉 Perl 您的源代码是 UTF-8。这是无用的(尽管无害),因为您已将源代码限制为 ASCII。

使用/u, 你告诉 Perl 使用 , \s,\d的Unicode 定义\w。这是无用的(尽管无害),因为您不使用任何这些模式。

您没有对输入进行解码,因此您的输入仅由字节组成,因此您的类中的大多数字符(例如\x{2018})不可能匹配任何内容。你需要解码你的输入(当然,编码你的输出)。使用-CSD可能会这样做。

perl -CSD -i -pe'
   s/[\x{2018}\x{201A}\x{201B}\x{FF07}\x{2019}\x{60}]/\x27/g;
   s/[\x{FF02}\x{201C}\x{201D}\x{201E}]/"/g;
' text.txt
于 2012-10-01T20:57:42.380 回答