Also die Regex
Code:
(?<firstGroup>['"]?)(?<secondGroup>\d+)
Matched bei der Eingabe von '<h1 class="test" id="29">' folgendes:
Code:
[1]
firstGroup: []
secondGroup: [1]
["29]
firstGroup: ["]
secondGroup: [29]
Wie Du siehst, matched er also sogar das 1 von <h1 mit, weil Du die Hochkommas in ['"]? mit dem ? als Optional markiert hast. Ich habe hier die Backreference mal weggelassen, und so siehst Du dass nur "29 gematched wurde.
Durch das Hinzufügen der Backreference \1 an den Ausdruck wird die erste Gruppe (['"]?), also das optionale " oder ', wieder verwendet. Das ist das gleiche wie wenn Du
(['"]?)(\d+)(['"]?) schreiben würdest. Damit wird dann auch "29" gematched.
Schauen wir uns nun Deinen Zufallstreffer an:
Code:
(['"]?)(\d+)\1(\d+)\1
auflösen der Backreferenzen ==> (['"]?)(\d+)(['"]?)(\d+)(['"]?) Achtung: nicht GANZ korrekt! Siehe unten!
Der eigentliche Match sind die zwei (\d+) getrennt von einem optionalen Hochkomma:
und zwar nur, weil Du Backreferences verwendet hast.
Da die Backreferenz treffen muss, Deine Regex matched also nur, wenn ALLE optionalen Hochkommas vorhanden wären, also z.B. "2"9".
Was also gematched wird sind belibig viele Ziffern getrennt von einem Hochkomma, wenn die erste Gruppe eines findet und NICHT getrennt von einem Hochkomma, wenn die erste Gruppe keines findet.
Anderer Input: id="269" Match:
Code:
[269]
1: []
2: [26]
3: [9]
Wie Du siehst matched die Gruppe zwei erstmal so viel sie kann (Greedy) und erwischt die 26, die erste Gruppe matched nicht weil kein Hochkomma die dritter Gruppe (die andere (\d+)) abtrennt.
Deswegen bekommst Du auch die Hochkommas nicht mit.
Du hast also tatsächlich nur einen Zufallstreffer, eine einstellige ID würdest Du damit nämlich nie finden.
Was Du eigentlich willst ist
und von diesem Match nimmst Du nur den Wert aus der zweiten Gruppe.
Das = ist noch drin damit das 1 von h1 nicht mit gematched wird, sondern nur id="12" id='12' oder id=12.