Ogólne podejście do (odpowiednika) „referencji w klasie znaków”?

W regexach Perla wyrażenia takie jak\1, \2, itp. są zwykle interpretowane jako „odniesienia wstecz” do wcześniej przechwyconych grup, ale nie tak, gdy\1, \2, itd. pojawiają się w klasie postaci. W tym drugim przypadku\ jest traktowany jako znak ucieczki (a zatem\1 jest tylko1itd.).

Dlatego, jeśli (na przykład) jeden chciał dopasować łańcuch (o długości większej niż 1), którego pierwszy znak pasuje do ostatniego znaku, ale nie pojawia się nigdzie indziej w ciągu, następujące wyrażenie regularne będzienie robić:

/\A       # match beginning of string;
 (.)      # match and capture first character (referred to subsequently by \1);
 [^\1]*   # (WRONG) match zero or more characters different from character in \1;
 \1       # match \1;
 \z       # match the end of the string;
/sx       # s: let . match newline; x: ignore whitespace, allow comments

bynie działa, ponieważ dopasowuje (na przykład) łańcuch'a1a2a':

  DB<1> ( 'a1a2a' =~ /\A(.)[^\1]*\1\z/ and print "fail!" ) or print "success!"
fail!

Zazwyczaj udaje mi się znaleźć jakieś obejście1, ale zawsze jest raczej specyficzny dla problemu i zazwyczaj znacznie bardziej skomplikowany niż to, co bym zrobił, gdybym mógł użyć backreferences w klasie znaków.

Czy jestgenerał (i miejmy nadzieję, że proste) obejście?

1 Na przykład w przypadku problemu z powyższego przykładu użyłbym czegoś takiego

/\A
 (.)              # match and capture first character (referred to subsequently
                  # by \1);
 (?!.*\1\.+\z)    # a negative lookahead assertion for "a suffix containing \1";
 .*               # substring not containing \1 (as guaranteed by the preceding
                  # negative lookahead assertion);
 \1\z             # match last character only if it is equal to the first one
/sx

... gdzie zastąpiłem dość proste (choć, niestety, niepoprawne) podwyrażenie[^\1]* we wcześniejszym wyrażeniu regularnym z nieco bardziej zakazującym twierdzeniem o negatywnym spojrzeniu(?!.*\1.+\z). To stwierdzenie w zasadzie mówi „zrezygnuj, jeśli\1 pojawia się gdziekolwiek poza tym punktem (innym niż na ostatnim stanowisku). „Nawiasem mówiąc, podaję to rozwiązanie, aby zilustrować rodzaj obejść, o których wspomniałem w pytaniu. Nie twierdzę, że jest to szczególnie dobre.

questionAnswers(1)

yourAnswerToTheQuestion