我试图用单引号或双引号替换各种字符。
这是我的测试文件:
# 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
但只有反引号字符才能被正确替换。我认为它与其他代码点太大有关,但我找不到任何关于此的文档。
这里我有一个one-liner转储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 `
为什么我的正则表达式不匹配?
答案 0 :(得分:17)
它不匹配,因为您忘记了对Perl的调用中的-CSAD
,并且未在您的环境中设置$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
我确实在this answer中提到过几次这样的事情。
答案 1 :(得分:7)
使用use utf8;
,您告诉Perl您的源代码是UTF-8。由于您已将源代码限制为ASCII,因此无用(尽管无害)。
使用/u
,您告诉Perl使用\s
,\d
,\w
的Unicode定义。这是无用的(虽然无害),因为你不使用任何这些模式。
您没有对输入进行解码,因此您的输入仅包含字节,因此您班级中的大多数字符(例如\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