Bei dieser Frage geht es um das Verhalten einer bestimmten Regex in TCL 8.5 in Vivado zu verstehen, insbesondere or
-ing zusammen zwei Regex-Teile bekomme ich unerwartete Ergebnisse:
Ich habe versucht, einen Block Text für die Befehlszeile mit regulären Ausdrücken einzurücken. Mein erster Gedanke war, jedes newline
durch ein newline
und einige spaces
(ersetzt durch X
hier zur besseren Übersicht) für den Einzug zu ersetzen, also:
Dadurch wird die erste Zeile nicht eingerückt, um der ersten Zeile, die ich ^
verwende, zu entsprechen:
Jetzt sollte es nur darum gehen, die beiden Regex-Teile mit einem |
zu kombinieren, aber ich bekomme eine Ausgabe, die ich nicht erklären kann:
Woher kommen die zusätzlichen Zeilenumbrüche und Identifizierungskennzeichen ( X
)? Warum sieht es so aus, als ob ich zwei Ersetzungen bekomme? Ist das ein Fehler, oder verstehe ich die Syntax für reguläre Ausdrücke nicht?
Um der Vollständigkeit willen ist hier die Regex, die ich jetzt puts [regsub -all -line "^" "foo\nBar\nBaz" "XX"]
Ich glaube, die Erklärung hängt von der Tatsache ab, dass der Ausdruck ^
als einfacher regulärer Ausdruck (BRE) behandelt wird. Wenn Sie jedoch |
hinzufügen, wird er wie ein erweiterter regulärer Ausdruck (ARE) behandelt Obermenge von erweiterten regulären Ausdrücken (ERE). Dies basiert auf der folgenden re_syntax-Manpage :
Ein ARE besteht aus einem oder mehreren Zweigen, die durch "|" voneinander getrennt sind und zu allem passen, was zu einem der Zweige passt.
Der zweite Teil des Puzzles ist, dass ^
in grundlegenden und erweiterten / erweiterten regulären Ausdrücken unterschiedlich behandelt wird. In einem einfachen regulären Ausdruck hat ^
nur dann eine spezielle Bedeutung, wenn es das erste Zeichen des Ausdrucks ist. Nochmals, von der re_syntax-Manpage :
BREs unterscheiden sich in einigen Aspekten von EREs ... ^ ist ein gewöhnliches Zeichen, außer am Anfang des RE oder am Anfang eines geklammerten Teilausdrucks, ...
Mit anderen Worten: ^
stimmt bei einem BRE nur mit dem Anfang der Zeichenkette überein, in einer ARE hingegen mit dem Anfang einer Zeile.
Also, was genau passiert gerade?
Erstens stimmt ^
mit dem Anfang einer Zeichenkette überein und ersetzt sie durch die Ersetzung \nXX
. Als nächstes sieht es f
, dann o
, dann o
, von denen keiner übereinstimmt. Dann sieht es '\ n', mit dem es übereinstimmt, also ersetzt es es durch den Ersatz.
Zu diesem Zeitpunkt hat der Matcher die Zeichen foo\n
verbraucht. Was bleibt, ist Bar\nBaz
. Der Matcher betrachtet nun diese Zeichenfolge, und das Muster ^
stimmt überein, sodass es erneut durch die Ersetzung ersetzt wird. Sie erhalten also zwei Kopien der Ersetzungszeichenfolge, eine für die neue Zeile und eine für den Anfang der verbleibenden Zeichenfolge.
Wenn Ihr Endziel darin besteht, jeder Zeile Einrückungen hinzuzufügen, können Sie eine Zeilenumbruch-Erkennung mit regsub verwenden und dann ^
verwenden, um jede Zeile einschließlich der ersten Zeile abzugleichen, anstatt beide Zeilenumbrüche und den Anfang der Zeichenfolge zu vergleichen . Dies tun Sie, indem Sie die --line
-Option zu regsub
hinzufügen. Zum Beispiel: