首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在perl regex替换命令中使用unicode字符?

如何在perl regex替换命令中使用unicode字符?
EN

Stack Overflow用户
提问于 2021-12-15 04:05:10
回答 4查看 278关注 0票数 2

当使用unicode字符(在Ubuntu中)时,这是行不通的:

代码语言:javascript
复制
$ perl -pC -e's/[à]/a/gu' <<< 'à'
à
$ perl -pC -e's/[b]/a/gu' <<< 'b'
a

尽管它似乎得到了PCRE的支持(至少根据regex101)。

我做错什么了?我在perl命令中遗漏了一些标志吗?

在javascript中,这个“只起作用”,所以如果我可以在命令行中为它提供一个简单的一行程序,我就会使用节点.但是我仍然想知道为什么perl命令不能工作。

就背景而言:

我试图使用诸如/[àâáãä]/a/g/[òôóõö]/o/g等替换词来对字典文件(即删除单词列表中的重音等)进行排序,这样我就可以使用它来使拼写检查重音变得不敏感(例如,在IntelliJ中)。

基本上,以下是制作一本“酸化”额外词典的步骤:

  1. 下载语言的.dic文件(所有单词的列表)
  2. 使用grep筛选包含非ascii/可替换字符的单词。
  3. 连续使用regex替换使单词重音不敏感
  4. 在IDE中导入经过酸化的.dic文件(除了标准语言字典)
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-12-15 08:11:57

所有这些的一个实用方法是使用正文:Unidecode

代码语言:javascript
复制
perl -C -MText::Unidecode -pe'unidecode($_)'  <<< 'à'

打印a。该模块将Unicode文本音译为纯文本ASCII。

另一种方法:使用Unicode::规范化对字符(“正常化”)进行分解,以便将字符及其判读标记 (组合重音)分离为它们自己的代码点,同时它们仍然形成一个有效的字素,然后使用简单的正则表达式删除diacriticals (\p{NonspacingMark}\p{Mn})。

这两种方式都有例外和边缘情况,但我认为它可能只是做你需要的。

至于包含特定(文字)字符的代码,需要告诉Perl,程序源是UTF-8,通过带有utf8语用use utf8;或带有命令行标志-Mutf8

代码语言:javascript
复制
perl -C -Mutf8 -pe's/[à]/a/g' <<< 'à'
票数 8
EN

Stack Overflow用户

发布于 2021-12-15 08:37:40

您需要添加-Mutf8来告诉Perl程序是使用UTF-8而不是ASCII编码的。

代码语言:javascript
复制
$ perl -pC -Mutf8 -e's/[à]/a/gu' <<< 'à'
a
票数 4
EN

Stack Overflow用户

发布于 2021-12-17 06:56:12

简单的回答是将-Mutf8添加到命令行中。

如果您不确定Perl如何解释您在命令行中所写的内容,您可以让它用核心B::perlstring()函数将其吐回给您,或者用B::Deparse离开整个脚本。这会很快地说明你的问题。(括号中的“à”字符在这里没有任何作用。)

代码语言:javascript
复制
$ perl -MO=Deparse -pC -e 's/à/a/gu' <<< 'à'
代码语言:javascript
复制
LINE: while (defined($_ = <ARGV>)) {
    s/\303\240/a/gu;
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

看看你的替代词是怎么有两个字符的?

然后,您可以立即看到use utf8如何解决您的问题。

代码语言:javascript
复制
$ perl -MO=Deparse -Mutf8 -pC -e 's/à/a/gu' <<< 'à'
代码语言:javascript
复制
use utf8;
LINE: while (defined($_ = <ARGV>)) {
    s/\340/a/gu;
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK

您可以使用perlstring()来确保Perl接收到您认为的输入。

代码语言:javascript
复制
$ perl -p -MB -E 'say B::perlstring($_)' <<< 'à'
"\303\240\n"
à
代码语言:javascript
复制
$ perl -pC -MB -E 'say B::perlstring($_)' <<< 'à'
"\x{e0}\n"
à

您可以看到,如果没有-C,Perl将接收两个分解的字符。

根据具体情况,Perl将字符转储为八进制代码(\340)或十六进制代码(\xE0)。请注意,在这里,您始终可以用转义代码版本替换命令行中的原始unicode字符。这是一个很好的方式来明确什么否则将是模棱两可。

代码语言:javascript
复制
$ perl -pC -e 's/[\xE0]/a/gu' <<< 'à'
a

如果您不想记住UTF8模式,可以将这些选项插入到PERL5OPT环境变量中,或者创建一个shell别名。小心这是全球性的!

代码语言:javascript
复制
$ export PERL5OPT='-C -Mutf8'
$ perl -MO=Deparse -p -e 's/à/a/gu' <<< 'à'
代码语言:javascript
复制
use utf8;
LINE: while (defined($_ = <ARGV>)) {
    s/\340/a/gu;
}
continue {
    die "-p destination: $!\n" unless print $_;
}
-e syntax OK
代码语言:javascript
复制
$ perl -MB -p -E 'say B::perlstring($_)' <<< 'à'
"\x{e0}\n"
à

或者作为外壳化名。

代码语言:javascript
复制
alias uperl='perl -C -Mutf8'

有关如何使用瑞士陆军链锯命令行的更多信息,请参见perlrun

另见B::Deparse

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70358309

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档