RegEx: Mathematische Berechnung mit Latex Befehl


#1
Hallo :D

ich würde gern einen "normalen" mathematischen Term via RegEx in LaTex darstellen. Das Problem bezieht sich nur auf das Divisionszeichen. Mit Hilfe dieser Ersetzung sollen Divisionsaufgaben als saubere Brüche dargestellt werden.
Ein Bruch wird in LaTex mit \frac{2}{3} erzeugt für den Bruch 2/3.

Der Suchstring soll im Zähler als auch im Nenner folgendes erkennen:
  • Ganze Zahlen
  • Dezimalzahlen
  • Klammerausdrücke
  • eine Variable der Form x_{1} bzw. x_{1234} :D
An sich funktioniert alles, nur dass der Klammerausdruck nicht korrekt erkannt wird.

SuchString:
(\(.*?\)|\d*\.\d*|\d*|x_{\d*})\/(\(.*?\)|x_{\d*}|\d*\.\d*|\d*)

Ersetzung erfolgt über:
\\frac{$1}{$3}

Vermutlich wird die 2. Gruppierung nie benötigt :D

  • Das Divisionszeichen wurde bereits von / nach \div geändert.
  • Das Malzeichen wurde bereits von * nach \cdot geändert.
  • Wird im Nenner (unten) die Variable der Form x_{212} eingefügt, so wird ein Leerzeichen vorangestellt, um Fehler mit u.a. \cdot zu vermeiden bzw. \cdotx_{123} - wird von LaTex nicht korrekt umgesetzt, daher ein Leerzeichen.
Die Anwendung der RegEx erfolgt über eine While Schleife, um verschachtelte Ausdrücke zu erkennen. Also Divisionsaufgaben innerhalb von Klammerausdrücken

Beispieleingabe:
(3-9/ x_{11})- x_{8}/20.7+(20-9* x_{11}/50)/20

Ersetzung von / nach \div und * nach \cdot:
(3-9\div x_{11})- x_{8}\div20.7+(20-9\cdot x_{11}\div50)\div20

Ausgabe (ist - fehlerhaft):
x=\frac{(3-\frac{9}{ x_{11}})- \frac{x_{8}}{20.7}+(20-9\cdot \frac{x_{11}}{50})}{20}

Ausgabe (soll)
x=(3-\frac{9}{ x_{11}})- \frac{x_{8}}{20.7}+\frac{(20-9\cdot \frac{x_{11}}{50})}{20}

Wie müsste der Suchstring abgeändert werden? Es betrifft nur die Erkennung der Klammern im mathematischen Ausdruck.

Danke!! - Es ist vermutlich "nur" eine Kleinigkeit :D
 
#2
Ok, teilweise gelöst:
(\(.*?\)|\d*\.\d*|\d*|x_{\d*})\/(\(.*?\)|x_{\d*}|\d*\.\d*|\d*)
wurde geändert in
(\(
[^(]*?\)|\d*\.\d*|\d*|x_{\d*})\/(\(.*?\)|x_{\d*}|\d*\.\d*|\d*)

Neues Problem,
z.T. wird auch ersetzt, obwohl die Gruppierung leer ist. Wie kann man das verhindern?
Bsp.: \frac{}{22}

Ziel: Keine ersetzung vornehmen, wenn Gruppierung leer


 
#4
Ja, RegEx sind Reguläre Ausdrücke. Der Suchstring besteht aus 2 Gruppierungen - dem Zähler und dem Nenner. Leider wird auch ersetzt, wenn der Zähler quasi nicht gefunden wurde.

Bsp:

5/3 wird korrekt umgebaut zu \frac{5}{3}

ABER

5/3/2 wird leider nicht zu \frac{5}{3}/2 sondern zu \frac{5}{3}\frac{}{2}

Wie kann ich das beheben?
Der Suchstring ist:
(\([^(]*?\)|\d*\.\d*|\d*|x_{\d*})\/(\(.*?\)|x_{\d*}|\d*\.\d*+|\d*)

Die Ersetzung erfolgt über
\\frac{$1}{$2}


getestet auf https://regex101.com/r/Y8cWDp/1/
 

ComFreek

Mod | @comfreek
Moderator
#5
Hallo Dj.Nuss!

bist du gezwungen, es mit regulären Ausdrücken umzusetzen?
Ich bezweifle etwas, dass sie das Mittel der Wahl hier sind. Insbesondere kannst du mit ihnen rein theoretisch gesehen schon keine Klammerausdrücke parsen (nur reguläre Sprachen). Es gibt zwar hier und da Erweiterungen in den konkreten Implementierungen von RegExps gegenüber dem akademischen Kostrukt, aber selbst bei denen bin ich mir unsicher, ob das ein Spaß werden wird, damit Klammern zu parsen ;)

Related: https://stackoverflow.com/a/1732454/603003

Wenn du nicht einen Regex haben möchtest, der ständig bei neuen Eingaben kaputt geht, empfehle ich dir einen echten Parser zu nutzen, der auch mit Präzedenzen (etwa bei 5/3/2) zurecht kommt. Unter dem Stichwort "Parser Generator" findest du Tools, die dir aus einer Grammatik (welche recht leicht sein sollte für deine Terme) einen Parser vollautomatisiert generieren.
Ich habe bisher nur mit solchen Parser Generator für JS gearbeitet, für Java soll ANTLR angeblich ganz gut sein: http://www.antlr.org/.
 
Zuletzt bearbeitet:
#6
Es wäre schön, wenn es mit RegEx funktionieren könnte. Derzeit passt der Ausdruck zu 99%. Nur eben bei dem beschrieben Problem
5/3/2 wird leider nicht zu \frac{5}{3}/2 sondern zu \frac{5}{3}\frac{}{2}
wird es leider noch nicht korrekt umgesetzt.

Ich selber verwende diese Umwandlung in Objektiv-C (Xcode) - Daher wäre es schön, wenn ich einen String A in einem String B wie gewünscht umwandeln könnte. Schön wäre es, wenn jemand, der auf dem Gebiet sicher unterwegs ist, sich dies einem anschauen könnte und den vorhandenen
(\([^(]*?\)|\d*\.\d*|\d*|x_{\d*})\/(\(.*?\)|x_{\d*}|\d*\.\d*+|\d*)
entsprechend abändern könnte - siehe: