/^(?<!XDG_) [_A-Z0-9]+ _PATH$/x does not make sense to me, you are trying to look before the beginning of the string.
How about:
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11166082
use warnings;
my @patterns = qw/PKG_CONFIG_PATH XDG_DATA_DIRS XDG_SEAT_PATH XDG_SESS
+ION_PATH/;
my $re = qr/^(?!XDG_ [_A-Z0-0]+ _PATH$)/x;
for ( @patterns )
{
print /$re/ ? " match" : "no match", " $_\n";
}
Outputs:
match PKG_CONFIG_PATH
match XDG_DATA_DIRS
no match XDG_SEAT_PATH
no match XDG_SESSION_PATH