开发者

Is there a neat way to invert an embedded pattern-match in a regular expression in Perl?

All, I have the following code:

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);

I'd like to replace the punctuation vomit within the regex with the pattern defined as $CTRL_CHARS. However, when I put something like: [^$CTRL_CHARS], Perl complains, because this is expanded out as [^(?msx-i:[|!?*])]. Understandably, Perl pitches a fit at the invalid character range x-i.

One solution would be to use the following:

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

There's repetition there, which I don't like... but they're close together, so maybe that's not such a bad thing.

What I'd like to know is if there's a simple way to invert the meaning of $CTRL_CHARS, either for the definition of $NON_CTRL_CHARS or for direct use within the regex.

Another approach would be to define a character class, but I don't know how to do that and can't find any 开发者_JAVA技巧simple one liners to do it (would have to be a simple one liner, I think, to justify it)


If $CTRL_CHARS is guaranteed to be a char class, then you can use

(?! $CTRL_CHARS . )

But why not just define

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

[$CTRL_CHARS]
[^$CTRL_CHARS]
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜