有没有一种巧妙的方法来反转Perl中正则表达式中的嵌入式模式匹配?

Dan*_*umb 1 regex perl

全部,我有以下代码:

Readonly my $CTRL_CHARS => qr{[|!?*]}xsm;

my ($dbix_object, $alias, $cardinality) = ($object =~ qr{
        ^                 # Start of the line
        ([^|*?!]*)        # Anything that isn't a relationship control character
                          #   i.e.    | (indicating an alias)
                          #           * (indicating many_to_many)
                          #           ? (indicating might_have)
                          #           ! (indicating has_one)
        \|?               # Possible |, indicating an alias follows
        ([^|!?*]*?)       # Possible alias (excludes all the control characters above)
        ([|!?*]?)$        # Possible control character
       }oxsm);
Run Code Online (Sandbox Code Playgroud)

我想用正则表达式替换标点符号中的标点符号vomit $CTRL_CHARS.然而,当我提出类似的东西:[^$CTRL_CHARS],Perl抱怨,因为这扩大了[^(?msx-i:[|!?*])].可以理解的是,Perl会在无效字符范围内进行调整x-i.

一种解决方案是使用以下内容:

Readonly my $CTRL_CHARS     => qr{[|!?*]}xsm;
Readonly my $NON_CTRL_CHARS => qr{[^|!?*]}xsm;
Run Code Online (Sandbox Code Playgroud)

那里有重复,我不喜欢......但他们是在一起,所以也许这不是一件坏事.

我想知道的是,是否有一种简单的方法来反转其含义$CTRL_CHARS,无论是$NON_CTRL_CHARS在正则表达式中的定义还是直接使用.

另一种方法是定义一个字符类,但我不知道如何做到这一点,并且找不到任何简单的一个衬里来做它(我认为必须是一个简单的衬垫来证明它)

ike*_*ami 7

如果$CTRL_CHARS保证是char类,那么你可以使用

(?! $CTRL_CHARS . )
Run Code Online (Sandbox Code Playgroud)

但为什么不定义

Readonly my $CTRL_CHARS => '|!?*';

[$CTRL_CHARS]
[^$CTRL_CHARS]
Run Code Online (Sandbox Code Playgroud)

  • @Dancrumb,我记得你可以创建自定义角色属性,并且它们是可以否定的.它们在perlunicode中被描述(http://perldoc.perl.org/perlunicode.html#User-Defined-Character-Properties). (2认同)