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]
精彩评论