PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Verwerfen von Ausdrücken in eckigen Klammern



DieterH
14-01-2010, 06:42
Hallo,

ich arbeite sehr viel mit benutzerdefinierten Makros in LaTeX, und möchte bezgl. deren Verwendung eine wirkungsvolle Qualitätssicherung betreiben. Diese erfolgt in einem Skript.

LaTeX-Makros sind Zeichenfolgen, die folgenden Aufbau haben (Beispiel):
\MyMacro[abc]{xyz}

"\MyMacro" ist der Name des Makros, ein optionaler Parameter, hier "abc" ist in eckigen Klammern eingeschlossen, und Pflichtargumente dahinter in jeweils geschweiften Klammern; hier nur ein Pflichtparameter "xyz".

Für das Herauslösen (der Einfachheit: Verwerfen) des OPTIONALEN Parameters verwende ich:
> echo "\\MyMacro[abc]{xyz}" | sed -e 's/\[[a-z]\{1,\}\]//g'
\MyMacro{xyz}

In manchen Fällen besteht der optionale Parameter nicht nur aus Buchstaben (a-z), sondern auch aus Sonderzeichen, z.B. ":". Es ist nicht schwierig, den Doppelpunkt an geeigneter Stelle einzufügen.

Ich möchte jedoch die Menge der zulässigen Zeichen für den optionalen Parameter allgemeiner gestalten; es sollen fast alle Zeichen mit Ausnahme der eckigen Klammern zugelassen werden. Die Abänderung der obigen SED-Anweisung in

> echo "\\MyMacro[abc]{xyz}" | sed -e 's/\[[^[]]\{1,\}\]//g'
\MyMacro[abc]{xyz}

führt nicht zum gewünschten Ergebnis. Auch das Maskieren der eckigen Klammern versagt, wie

> echo "\\MyMacro[abc]{xyz}" | sed -e 's/\[[^\[\]]\{1,\}\]//g'
\MyMacro[abc]{xyz}

belegt.

Wer kann mir einen Tipp geben, der die gewünschte Lösung bringt?

Vielen Dank im voraus.

Gruss
Dieter

jeebee
14-01-2010, 14:20
echo "\\MyMacro[abc]{xyz}" | sed -r 's#\[[^]]*\]##g'

-e ist überflüssig

DieterH
14-01-2010, 20:35
Hallo JeeBee (GB?),

danke für Deine Lösung. Ich habe sie erfolgreich ausprobiert. Jetzt sind aber drei Fragen aufgetaucht:

1. Das "^"-Zeichen in einer eckigen Klammer steht für "kommt nicht vor". Warum ist dann in einem funktionstüchtigen Lösungsansatz nur "]" als auszuschließendes Zeichen angegeben und nicht auch "["?

2. Dem optionalen Argument in [..] folgt zwingend der erste Pflichtparameter. Wenn ich dessen öffnende linke Klammer im Suchargument angebe, erhalte ich eine Fehlermeldung, dass die schließende Klammer fehlt.

3. Gibt es ein brauchbares Tutorial über die Verwendung erweiterter Ausdrücke, die mit der Option "-r" angegeben werden können? Ich fand kein Tutorial.

Danke
Gruss
Dieter

jeebee
14-01-2010, 21:11
1. Das "^"-Zeichen in einer eckigen Klammer steht für "kommt nicht vor". Warum ist dann in einem funktionstüchtigen Lösungsansatz nur "]" als auszuschließendes Zeichen angegeben und nicht auch "["? Wenn du versuchst auch noch [ anzugeben, was nicht nötig sein sollte, da du ja alles innerhalb von [ und ] löschen willst & nur ein optionales Argument möglich ist, dann reicht die Zeichenklasse [^]] (alles ausser einem ]). Wenn du trotzdem alles ausser [ und ] haben willst, musst du das wie folgt machen: \[[^][]*\].
Denn wenn du \[[^[]]*\] schreibst, dann passiert folgendes:
\[[^[]]*\] Rot: öffnen einer Zeichenklasse; diese wird im Ausdruck nicht wieder geschlossen
Blau: Zeichenklasse, welche als einziges Zeichen ] enthält.
Und wenn du \[[^\[\]]*\] schreibst, wird der blaue Teil als Zeichenklasse, bestehend aus den Zeichen ^ [ ], angesehen.


2. Dem optionalen Argument in [..] folgt zwingend der erste Pflichtparameter. Wenn ich dessen öffnende linke Klammer im Suchargument angebe, erhalte ich eine Fehlermeldung, dass die schließende Klammer fehlt. Wenn du die öffnende linke Klammer ({) im Suchstring hast, aber nicht im Ersetzungsstring, dann fehlt sie auch im Resultat (\MyMacroxyz}) was dann (in LaTeX?) zu der Fehlermeldung wegen der Klammern führt.


3. Gibt es ein brauchbares Tutorial über die Verwendung erweiterter Ausdrücke, die mit der Option "-r" angegeben werden können? Ich fand kein Tutorial.
In diesem Beispiel wäre das -r gar nicht nötig, als Tutorials gibts zum Beispiel das hier regular-expressions.info/tutorial.html (english) (http://www.regular-expressions.info/tutorial.html) oder die Kapitel zu Regexes (7-9) im Llama-Buch: Wiki (http://en.wikipedia.org/wiki/Learning_Perl), Amazon.de (http://www.amazon.de/Einf%C3%BChrung-Perl-Randal-L-Schwartz/dp/3897211475/ref=ed_oe_p)

Zum regex debuggen gibts Editoren, die gutes Syntax-Highlighting haben oder du kannst auch http://myregexp.com/ brauchen.

DieterH
15-01-2010, 05:50
Merci beaucoup

msi
16-01-2010, 15:11
kann dir auch die perlre man pages ans herz legen,
weiß jetzt nicht ob sed dazu kompatibel ist aber
mit perl kann man grundsätzlich dasselbe wie mit sed machen, würde
dann so aussehen:

echo "\\MyMacro[abc]{xyz}" | sed -r 's#\[[^]]*\]##g'

wird zu

echo "\\MyMacro[abc]{xyz}" | perl -npe 's#\[[^]]*\]##g'

http://perldoc.perl.org/perlre.html

jeebee
16-01-2010, 16:47
In perl würde es sogar noch eleganter mit non-greedy-star gehen:
echo "\\MyMacro[abc]{xyz}" | perl -npe 's#\[.*?\]##g'

Im Prinzip (falls immer nur 1 Argument in eckigen Klammern vorhanden ist) geht sogar .* (ohne non-greedy) und das global am Schluss wäre auch nicht nötig:
echo "\\MyMacro[abc]{xyz}" | sed 's#\[.*\]##'

DieterH
13-01-2011, 20:05
Hallo,

ich möchte mit SED von den drei folgenden Zeichenketten die geschweiften Klammern ersetzen:
##abrA{abc}
##abrB{abc}{def}
##abrC{abc}{def}{ghi}

allerdings nur dann, wenn vor ihnen das Präfix ##abrA, ##abrB und ##abrC steht. Die Inhalte in den geschweiften Klammern können beliebig lang sein.

Für einen Ansatz auf der Grundlage BASIC regular expression habe ich eine Lösung, z.B. für ##abrA{abc}:
s/\(##abrA\)\({\)\([^{}]\{1,\}\)\(}\)/\1@@CURLYL01@@\3@@CURLYR01@@/g
wobei die Zeichenketten @@CURLYL01@@ und @@CURLYR01@@ die Ersatzzeichenketten sind.

Ich möchte auf die EXTENDED regular expression (ERE) umsteigen, also "sed -r -f datei <eingabe > ausgabe"; bekomme aber jeweils Syntaxfehler für die Ersetzungsanweisungen, z.B.
s/(##abrA)({)(\[[^{}+\])(})/\1@@CURLYL01@@\1@@CURLYR01@@/g

Wie lauten die korrekten SED-Anweisungen für die o.g. 3 Zeichenketten auf der Grundlage von ERE?

Vielen Dank im voraus

Gruss
Dieter