Laden...

[erledigt] Regex mit Variablen, nur eine wird ersetzt, string = string neu?

Erstellt von Stryder vor 16 Jahren Letzter Beitrag vor 16 Jahren 1.763 Views
S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren
[erledigt] Regex mit Variablen, nur eine wird ersetzt, string = string neu?

Hallo,

hab mich gerade extra angemeldet weil ich mit meinem Problem einfach nicht fertig werde.
Habe schon alles abgesucht aber einfach keine Lösung gefunden.

Ich habe ein Programm geschrieben das mit Plugins gefüttert werden kann.
Diese Plugins haben eine Methode in der ein Variablenname definiert wird. (Variablename)
Das Host Programm ruft diesen Variablennamen ab und soll ihn mit dem ersetzen, was im Plugin unter (Variable) ausgegeben wird.

In einer XML Datei stehen die zu überprüfenden Strings.
Diese sollen dann nach Variablenamen aller Plugins durchsucht werden.

In der XML könnte also z.B. stehen: Hallo, es ist <uhrzeit> am <datum>

Das Ergebnis soll so aussehen: Hallo, es ist 14:23 am 15.02.2008

Es geht aber immer nur eine anzeige, entweder uhrzeit oder datum, jenachdem welches Plugin als letztes geladen wird (hängt vom Dateinamen ab)

Also so:

Hallo, es ist 14:23 am <datum>

oder so:

Hallo, es ist <uhrzeit> am 14.02.2008

mp ist ein LCD display das das ganze anzeigen soll.

Wenn nur ein Plugin vorhanden ist wird natürlich nur eins ersetzt, aber alle Plugins funktionieren einzeln.

Ich würde mich wirklich freuen wenn mir jemand helfen kann.
Sollten noch Fragen offen sein, bitte einfach fragen.


            //Die ArrayListen werden erstellt, denen die Variablenamen der einzelnen               
            //Plugins hinzugefügt werden sollen
            ArrayList variablename = new ArrayList();
            ArrayList variable = new ArrayList();
            //Der Ordner in dem nach Plugins gesucht werden soll wird definiert
            Global.Plugins.FindPlugins(Application.StartupPath + @"\Plugins");

            //In der folgenden Schleife soll für jedes Plugin einmal der Variablenname 
            //(z.B. <datum>) und der Wert (z.B: 03.02.2008) zu den Arrays hinzugefügt 
            //werden
            foreach (Types.AvailablePlugin pluginOn in Global.Plugins.AvailablePlugins)
            {
                variablename.Add(pluginOn.Instance.Variablename);
                variable.Add(pluginOn.Instance.Variable);
            }

            //Hier werden die Object Arrays zu String Arrays umgeschrieben, um sie 
            //später beim Replace Befehl benutzen zu können
            string[] name = (string[])variablename.ToArray(typeof(string));
            string[] replace = (string[])variable.ToArray(typeof(string));

            //Die Strings die nachher ausgegeben werden sollen, werden definiert.
            string output = null;
            string output2 = null;
            string output3 = null;

            //Die XML Datei mit den Ausgangs strings wird geladen
            //z.B. Es ist <uhrzeit> am <datum>
            XmlDocument xmlDoc = new XmlDocument();
            XmlNodeList nodeList = null;
            xmlDoc.Load("settings2.xml");
            nodeList = xmlDoc.DocumentElement.SelectNodes("//Einstellungen/Screens/*");
            
            //Solange der Wert vary == 1 ist wird die Schleife ausgeführt
            //Wird er in 0 verändert, durch den Button Stop, hört die Schleife beim 
            //nächsten Durchgang auf
            while (vary == 1)
            {
                foreach (XmlNode n in nodeList)
                {
                    //Die XML Knoten mit den Strings werden geladen
                    XmlNode zeile1text = xmlDoc.SelectSingleNode("//Einstellungen/Screens/" + n.Name + "/Zeile1");
                    XmlNode zeile2text = xmlDoc.SelectSingleNode("//Einstellungen/Screens/" + n.Name + "/Zeile2");
                    XmlNode zeile3text = xmlDoc.SelectSingleNode("//Einstellungen/Screens/" + n.Name + "/Zeile3");
            
                    int i;
                    //Die Ersetzen Methode soll solange arbeiten, bis alle Variablen durch 
                    //ihre Werte ersetzt wurden
                    for (i = 0; i < variablename.Count; i++)
                    {
                        //Den Werten Output wird der neue Wert zugewiesen
                        output = Regex.Replace(zeile1text.InnerText, name[i], replace[i]);
                        output2 = Regex.Replace(zeile2text.InnerText, name[i], replace[i]);
                        output3 = Regex.Replace(zeile3text.InnerText, name[i], replace[i]);
                        
                        //Hier wird der Wert zeile1text.innertext mit dem neuen wert output    
                        //ersetzt, hoffe ich?
                        output = output.Replace(zeile1text.InnerText, output);
                        output2 = output2.Replace(zeile2text.InnerText, output2);
                        output3 = output3.Replace(zeile3text.InnerText, output3);
                    }
                    //Dem LCD Display werden die fertigen Strings übergeben
                    mp.SetLine(0, output);
                    mp.SetLine(1, output2);
                    mp.SetLine(2, output3);
                    if (vary == 0)
                    {
                        mp.CleanUp();
                    }
                    //Der Thread läuft als BackgroundTask ab, damit er um die Dauer der 
                    //Anzeige angehalten werden kann
                    XmlNode dauer = xmlDoc.SelectSingleNode("//Einstellungen/Screens/" + n.Name + "/Dauer");
                    Thread.Sleep(Convert.ToInt32(dauer.InnerText));

                }
                }
U
1.688 Beiträge seit 2007
vor 16 Jahren

Hallo,

hab erst einmal drei Bemerkungen:

  1. Bist Du sicher, dass die Schleife laufen soll, solange i≤Global.Plugins.AvailablePlugins.Count? Ich vermute, '<' wäre richtig.
  2. i sollte wahrscheinlich in der Schleife auch nur auf '<1' bzw. '==0' geprüft werden.
  3. Ich frag mich, warum überhaupt etwas Sinnvolles bei Plugin-Anzahl>1 herauskommen kann. Du setzt Deine Ausgabe outputzeile1 immer auf outputzeile12, welche immer "test" enthält.

Noch zu drittens: diese Zuweisungen mit Zwischenvariable können ersatzlos entfallen. Die Fallunterscheidung in der Schleife kann entfallen, wenn Du die Ausgabewerte mit den Inputs initialisierst.

Achso, noch was. Der Sinn der doppelten Schleife erschließt sich mir gerade nicht. Warum machst Du das?

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Ich habe den Anfangs Beitrag jetzt auf die Lösung von der Seite (http://forums.asp.net/p/1185961/2036998.aspx#2036998) angepasst.

Hier ein Zitat der Seite:

public string strSqlBlocker(string StrValue)
        {   
            string[] BadCharacters = { "Hello", "World", "And", "How" };
            string[] GoodCharacters = { "Goodbye", "Moon", "Without", "When" };
            string strReplaced = "";
    
            int i;
            for(i=0; i9            {
               strReplaced = StrValue.Replace(BadCharacters[i], GoodCharacters[i]);
           }
   
           return strReplaced;
           
       }

Ebenfalls von der Seite kommt dieser Tip, den ich allerdings nicht verstehe, danach soll es bei demjenigen der dort ein Problem hatte funktionieren, also könnte das auch mein Problem sein.

Inside the loop do

mystring = mystring.Replace(ch);

So you always have the new string replacing the old. Makes sense?

was ist da mit ch gemeint?

Vielen Dank schon mal für die Hilfe!

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Stryder,

Strings in C# sind immutable. Deshalb ändert Replace auch nicht den Original-String, sondern liefert einen neuen String, der die Ersetzungen enthält.

herbivore

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Hallo Herbivore,

danke für den Tip, aber wie könnte ich dann den String so speichern, das beim nächsten Durchlauf der zuvor bearbeitete weiter bearbeitet wird?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Stryder,

naja, eben genauso, wie in dem Zitat steht.

herbivore

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Aber wenn ich in meinen Code

output = ouput.replace(ch)

schreibe sagt er mir immer "Der Name "ch" ist im aktuellen Kontext nicht vorhanden.
Was ist mit ch gemeint? oder was muss ich dahinschreiben?

49.485 Beiträge seit 2005
vor 16 Jahren

Hallo Stryder,

naja, so wie du den Namen der Variable mit dem String angepasst hast, musst du natürlich auch die Parameter so anpassen, wie du es für die Ersetzung, die du vornehmen willst, brauchst.

Siehe unbedingt auch [Hinweis] Syntaxfehler selbst lösen (Compilerfehlermeldungen).

Und vielleicht auch [Hinweis] Wie poste ich richtig? Punkt 1.1.1, da wir in den letzten paar Posts schon über sehr elementare Dinge gesprochen haben, die wir eigentlich voraussetzen.

herbivore

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Hallo herbivore,

das ist echt zum verzweifeln, in dem Beispiel ist auch nirgends "ch" definiert. Ich versteh einfach nicht was damit gemeint ist.
Ich habe folgendes probiert:

Das müsste doch richtig sein oder?


                        output = output.Replace(zeile1text.InnerText, output);
                        output2 = output2.Replace(zeile2text.InnerText, output2);
                        output3 = output3.Replace(zeile3text.InnerText, output3);

aber dann wird wieder nur eine Variable mit ihrem Wert ersetzt?
Jeweils die, dessen Plugin zuletzt geladen wird.

U
1.688 Beiträge seit 2007
vor 16 Jahren

Schau Dir einfach mal die Dokumentation der String.Replace-Methode an.

Du wirst sehen, dass es ein Replace(ch) nicht gibt. Kann es auch gar nicht geben, denn mit einem Parameter kann nicht festgestellt werden, was womit ersetzt werden soll.

Du wirst auch sehen, dass Dein Code aus dem letzten Posting falsch ist.

Und schließlich - eigentlich wollte ich noch auf Deine Fragen auf mein Posting antworten. Das ist leider nicht mehr möglich, da Du wild in Deinen Postings herum editiert und sie dabei komplett verändert hast (Ausgangssituation, Fragen, Code). Das ist überhaupt keine gute Idee. s. [Hinweis] Wie poste ich richtig? Punkt 10.

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Also zur Dokumentation der String.Replace Methode habe ich folgendes unter dieser Adresse (http://msdn.microsoft.com/library/deu/default.asp?url=/library/DEU/cpref/html/frlrfsystemstringclassreplacetopic.asp) gefunden:

public string Replace(
   string oldValue,
   string newValue

müsste dann mein Code nicht eigentlich richtig sein?
zeile1text.InnerText wird mit output überschrieben um beim nächsten durchgang weiter bearbeitet zu werden?

Der Grund wieso ich meinen Eingangspost mehr oder weniger grundlegend geändert habe ist, weil ich nach deinem Post gemerkt habe das doch einiges sehr unsinnig war.

Also habe ich die Fehler die du genannt hast verbessert und dann den ganzen Code überarbeitet.
Die Fragestellung ist allerdings die gleiche geblieben.

U
1.688 Beiträge seit 2007
vor 16 Jahren

Wenn z. B. Dein Ausgangsstring (Zeile1) so aussieht: "Hallo, es ist <uhrzeit> am <datum>"

dann würdest Du schreiben:

Zeile1=Zeile1.Replace("<uhrzeit>","14:23");
Zeile1=Zeile1.Replace("<datum>","15.02.2008");

um das gewünschte "Hallo, es ist 14:23 am 15.02.2008" zu bekommen.

S
Stryder Themenstarter:in
26 Beiträge seit 2008
vor 16 Jahren

Ja soweit verstehe ich das ja, dass soll ja hier passieren:

output = Regex.Replace(zeile1text.InnerText, name_, replace_);

allerdings wird ja im ersten Durchgang z.b. aus

Hallo, es ist <uhrzeit> am <datum>

Hallo, es ist 14:56 am <datum>

und im zweiten Durchgang soll dann daraus

Hallo, es ist 14:56 am 15.12.2021 werden

und daher muss der Wert "zeile1text.InnerText" aktualisiert werden, damit beim nächsten durchlauf das 14:56 nicht vergessen wurde.

herbivore hatte gesagt das strings in C# immutable sind also nicht umgespeichert werden können, also muss zeile1text.innertext durch output ersetzt werden.

Und das habe ich mit diesem "output = output.Replace(zeile1text.InnerText, output);" zu machen...

aber ein simples

zeile1text.InnerText = output;

hätte es auch getan oO 😁

Jetzt gehts... danke an alle für die Hilfe.
Hier kann jetzt geschlossen werden.