QString::replace( )?

Alles rund um die Programmierung mit Qt
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

QString::replace( )?

Beitrag von Whitefurrows »

Hallo,

wie kann ich in einem String zwei Zeichen ersetzen? Die Strings sehen z.B. so aus:

"<123> Text" oder "Text <123> Text"

Jetzt möchte ich "<" durch "(" und ">" durch ")" ersetzen.

Um unnötige Deklarationen zu vermeiden habe ich mir das in etwa so vorgestellt:

Code: Alles auswählen

ui.label->setText( label->text().replace(QRegExp(???)) );
Hat jemand eine Idee wie das funktionieren kann?

Gruß,

Whitefurrows
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Ja, aber momentan keine Zeit das zu prüfen und bevor ich Müll schreibe, lass ich es lieber. Wenn Du es mit RegExp machen willst, dann studiere mal http://www.regular-expressions.info/. Danach solltest Du es alleine hin bekommen. Vergiss jedenfalls nicht die Gier abzuschalten :-)
setMinimum(...) ist das, IIRC. Ein weiteres Stichwort in der Qt-Doku wäre cap(int n).
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows »

Hallo,

in der Doku habe ich gesehen, das Qt nur folgendes kann:
QString & replace ( const QRegExp & rx, const QString & after )
aber ich brauche ja ein:

Code: Alles auswählen

QString & replace ( const QRegExp & rx, const QRegExp & rx )
wenn ich das richtig sehe.

Mit dem Versuch:

Code: Alles auswählen

ui.label->setText( label->text().replace( QRegExp("*?<|?>*"), "(" ) );
könnte ich ohnehin nur ein Zeichen ersetzen, wenn ich alles richtig verstanden habe! Abgesehen davon funktioniert dieses Beispiel auch nicht!

Kannst du es vielleicht einmal versuchen, auch auf die Gefahr das du Müll schreibst ;-)
Schlimmer wie mein Versuch kann es ja nicht werden!

Gruß,

Whitefurrows
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Code: Alles auswählen

.replace("<", "(").replace(">", ")");
bst
Beiträge: 56
Registriert: 7. November 2006 13:16
Wohnort: Ilsfeld

Beitrag von bst »

Hallo,

versuche das mal so:

Code: Alles auswählen

.replace( QRegExp("<([^<>]*)>"), "(\\1)")
cu, Bernd
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows »

Hey, das hat ja super funktioniert :-), besten Dank!

Allerdings habe ich in einem anderen Fall das Problem, das ich auch "[" und "]" ersetzen muss. Jetzt habe ich versucht das ganze zu ändern in

Code: Alles auswählen

.replace( QRegExp("\[([^\[\]]*)\]"), "[\\1]")
leider ohne Erfolg. So grob habe ich ja verstanden was du da machst, aber für was genau das "(\\1)" ist habe ich absolut nicht verstanden. Es wäre nett wenn du mir noch ein paar Worte dazu sagen könntest, damit ich auch verstehe was du da machst und ich nicht das nächstemal wieder Fragen muss.
Zandru
Beiträge: 84
Registriert: 29. Mai 2007 15:35

Beitrag von Zandru »

schau mal hier:
http://doc.trolltech.com/4.3/qregexp.ht ... uring-text

und aus http://doc.trolltech.com/4.3/qstring.html#replace :
For regular expressions containing capturing parentheses, occurrences of \1, \2, ..., in after are replaced with rx.cap(1), cap(2), ...

alles klar?
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows »

Super, vielen Dank für eure Hilfe, es funktioniert jetzt.

Ich versuche es einmal zu Erklären und ihr Ergänzt bzw. Korrigiert mich bitte ;-) um zu sehen ob ich es auch verstanden habe. Es muss ja nicht bedeuten, wenn es funktioniert, dass ich es auch richtig verstanden habe!

"<" und das ">" am Anfang und Ende sind die Zeichen die ersetzt werden sollen

"[...]" in dieser rechteckigen klammer werden alle erlaubten Zeichen aufgeführt

"^" mit diesem Zeichen wird zum Ausdruck gebracht, das die folgenden Zeichen negiert werden, womit alle Zeichen außer "<" und ">" erlaubt sind

"*" durch diesen Stern sind alle gültige Zeichen hinter dem Ausdruck erlaubt

"(...)" diese Klammer wird gesetzt, weil mehrere Ausdrücke zusammen gefasst werden

"\\1" damit wird die erste capturing parenthese gewählt und vor bzw. nach dieser wird ein "(" und ")" eingefügt.

Zeichen die für einen Ausdruck verwendet werden (z.B."[...]"), aber als Zeichen genutzt werden sollen, können durch ein Escape sequence wie "\\..." genutzt werden, weshalb mein Beispiel zuvor mit einem "\" nicht funktioniert hat.

War das soweit jetzt richtig?
bst
Beiträge: 56
Registriert: 7. November 2006 13:16
Wohnort: Ilsfeld

Beitrag von bst »

Abend,
War das soweit jetzt richtig?
Beinahe.

* bedeutet 0 oder mehrmals das vorangegangene Zeichen, so viele wie möglich.

Hier bezieht sich das also auf alle Zeichen außer < und >, bzw. außer [ und ].

(...) dient schon der Zusammenfassung von Teilausdrücken, das Wesentliche daran ist aber daß der geklammerte Teil in einem sogenannten SubMatch gespeichert wird auf den dann später via \nummer zugegriffen werden kann.

\1 im Ersatzstring ist der Inhalt des 1. SubMatches.

Innerhalb eines Strings werden ebenfalls \ als Spezialzeichen benutzt, deshalb muß man diese für QRegExp verdoppeln.
.replace( QRegExp("\[([^\[\]]*)\]"), "[\\1]")
Versuche es mal (ungetestet) mit:

Code: Alles auswählen

.replace( QRegExp("\\[([^\\[\\]]*)\\]"), "[\\1]")
Wobei dieses natürlich witzlos ist, da es ja nichts verändert.

cu, Bernd
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Es sollte auch nicht vergessen werden, das bisher Genanntes nur funktioniert, wenn der Suchstring nur einmal im String vorkommt. Tritt er mehrmals auf, werden nur die äußeren Klammern ersetzt.
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
bst
Beiträge: 56
Registriert: 7. November 2006 13:16
Wohnort: Ilsfeld

Beitrag von bst »

Morgen macman,

wie kommst Du darauf ?

Es werden alle Klammernpaare ersetzt, bei verschachtelten Klammern nur die innerste Ebene.

cu, Bernd
--

Code: Alles auswählen

#include <QDebug>
#include <QRegExp>
#include <QString>

int main(void)
{
	QRegExp rx("<([^<>]*)>");

	qDebug() << QString("a <1> b <234> c <5> d").replace(rx, "(\\1)");
	qDebug() << QString("a <1 b <2 c <345> d 6> e 7> f").replace(rx, "(\\1)");

	return 0;
} 
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

bst hat geschrieben:wie kommst Du darauf ?
Steht so in der Doku:
void QRegExp::setMinimal ( bool minimal )
Enables or disables minimal matching. If minimal is false, matching is greedy (maximal) which is the default.
For example, suppose we have the input string "We must be <b>bold</b>, very <b>bold</b>!" and the pattern <b>.*</b>. With the default greedy (maximal) matching, the match is "We must be <b>bold</b>, very <b>bold</b>!". But with minimal (non-greedy) matching, the first match is: "We must be <b>bold</b>, very <b>bold</b>!" and the second match is "We must be <b>bold</b>, very <b>bold</b>!". In practice we might use the pattern <b>[^<]*</b> instead, although this will still fail for nested tags.
bst hat geschrieben:Es werden alle Klammernpaare ersetzt, bei verschachtelten Klammern nur die innerste Ebene.
Stimmt, weil Du die Klammern im Suchstring negierst. Hab ich übersehen, Asche auf mein Haupt :-)
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows »

Hallo,

noch einmal vielen Dank für die tolle Hilfe und Erklärungen, habe jetzt alles verstanden!

Gruß

Whitefurrows
Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows »

Hallo,

ich habe doch noch eine Frage. Ich wollte jetzt noch alle Zeilenumbrüche ersetzen und habe folgendes versucht:

Code: Alles auswählen

.replace( QRegExp("<([^<>]*)>|(\s)"), "(\\1)\\2<br>")
Wie erwartet hat es auch nicht richtig funktioniert, da ich eine OR Verknüpfung hatte. Ich brauche aber eine UND Verknüpfung, also "+" aber dann macht er garnichts.
Also wie bekomme ich eine UND Verknüpfung hin mit der ich in allen Strings die ein "<>" und ein oder mehrere "\n" bzw. "\r\n\" enthalten ersetzen kann?

Gruß

Whitefurrows
bst
Beiträge: 56
Registriert: 7. November 2006 13:16
Wohnort: Ilsfeld

Beitrag von bst »

Hi Whitefurrows,

wenn Du alle Zeilenumbrüche ersetzen/löschen möchtest nimm vielleicht einfach noch einen 2. replace oder auch einen .remove hinzu.

Code: Alles auswählen

	QRegExp rx("<([^<>]*)>");
	QRegExp rx2("[\n\r]+");

	qDebug() << QString("a\n\n <1> b <2\n\r3\n\r4> c <5> d").replace(rx, "(\\1)").remove(rx2);
cu, Bernd
Antworten