如何在 perl 正则表达式中组合多个 Unicode 属性?

Posted

技术标签:

【中文标题】如何在 perl 正则表达式中组合多个 Unicode 属性?【英文标题】:How to combine multiple Unicode properties in perl regex? 【发布时间】:2017-08-31 12:48:26 【问题描述】:

有这个脚本:

use 5.014;
use warnings;

use utf8;    
binmode STDOUT, ':utf8';

my $str = "XYZ ΦΨΩ zyz φψω";

my @greek = ($str =~ /\pGreek/g);
say "Greek: @greek";

my @upper = ($str =~ /\pUpper/g);
say "Upper: @upper";

#my @upper_greek = ($str =~ /\pUpper+Greek/); #wrong.
#say "Upper+Greek: @upper_greek";

是否可以组合多个 unicode 属性?例如如何只选择Upper and Greek,然后得到想要的:

Greek: Φ Ψ Ω φ ψ ω
Upper: X Y Z Φ Ψ Ω
Upper+Greek: Φ Ψ Ω      #<-- how to get this?

【问题讨论】:

@HåkonHægland 这仍然会返回X Y Z 【参考方案1】:

我们要执行 AND 操作,所以不能使用

/(?:\pGreek|\pUpper)/         # Greek OR Upper

/[\pGreek\pUpper]/            # Greek OR Upper

在正则表达式中实现 AND 的一种方法是使用环视。

/\pGreek(?<=\pUpper)/         # Greek AND Upper

获得 AND 的另一种方法是否定 OR。 De Morgan's laws告诉我们

NOT( Greek AND Upper )  ⇔  NOT(Greek) OR NOT(Upper)

所以

Greek AND Upper  ⇔  NOT( NOT(Greek) OR NOT(Upper) )

这给了我们

/[^\PGreek\PUpper]/           # Greek AND Upper

从 5.18 开始,您还可以使用一个实验性功能:

use experimental qw( regex_sets );

/(?[ \pGreek & \pUpper ])/    # Greek AND Upper

【讨论】:

@jm666 NOT (NOT GREEK) OR (NOT UPPER) = GREEK AND UPPER 在正则表达式中没有开箱即用的AND 方式是否有原因? (类似于|OR @Zaid,除了 AND-THEN(如 "AB" = "A AND-THEN B"),你会做什么?如果您想 AND 字符属性,那么这就是创建 (?[ ]) 的原因。 /A/ &amp;&amp; /B/ 解决了对 AND 的另一个主要需求。【参考方案2】:

这也适用于 5.14.0:

sub InUpperGreek 
    return <<'END'
+utf8::Greek
&utf8::Upper
END


my @upper_greek = ($str =~ /\pInUpperGreek/g);
say "Upper Greek: @upper_greek";

不确定这是否更简单。 :) 有关其工作原理的更多信息,请参阅perlunicode 关于用户定义字符属性的文档。

【讨论】:

以上是关于如何在 perl 正则表达式中组合多个 Unicode 属性?的主要内容,如果未能解决你的问题,请参考以下文章

shell grep命令的多个正则表达式 组合使用。

如何在 Perl 中仅匹配 Unicode 字符串中的完全组合字符?

perl多个正则表达式匹配多行

Perl正则表达式例子

将多个正则表达式匹配之一分配给变量作为 Perl 单行(取消引用数组?)

Perl 正则表达式 |如何从文件中排除单词