Autor Beitrag
Csharp-programmierer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: So 04.09.16 14:00 
Hallo,
ich habe eine CSS Datei, die ja gewöhnlich so aussieht:
ausblenden Cascading Style Sheet
1:
2:
3:
#id1 {
.....
}


Die C# Anwendung soll nun alle ID's auslesen, also die Namen. In dem Beispiel wäre es dann id1. Wie mache ich das?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 04.09.16 14:12 
Entweder Du probierst einen CSS-Parser aus: stackoverflow.com/qu...e-a-css-parser-for-c

Oder Du verwendest Regex: #(?<id>\w[\w\d]*)
Bei Regex musst Du natürlich darauf achten, dass das auch entsprechend Flexibel genug ist und mit den Möglichkeiten in CSS klar kommt.
Mein Beispiel sucht alle Zeichenfolgen, die vorne ein #-Zeichen haben, mit einem Buchstaben beginnen und nur aus Buchstaben oder Zahlen bestehen.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 04.09.16 17:39 
Als Parser wäre AngleSharp zu empfehlen.

Das Regex ausreicht würde ich bezweifeln der Selektor Syntax in CSS ist da doch zu komplex. Das man nur die eine Selektorvariante (#id) braucht eher unwahrscheinlich.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: So 04.09.16 17:52 
@Ralf Jansen. Ich brauche wirklich nur die ID'S, da das Programm alle vorhandenen ID'S auslesen muss und dann eine neue ID generieren muss, die es noch nicht gibt. Und ich glaube dafür reicht der Regex.

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: So 04.09.16 21:11 
ausblenden C#-Quelltext
1:
2:
Regex regex = new Regex("#(?<id>\w[\w\d]*)");
                MessageBox.Show(regex.Match(t.Text).ToString());


Da steht jetzt als Fehler, dass Escapesequenz nicht erkannt wurden :(

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 04.09.16 21:18 
Setz ein @ vor den String.
Das Backslash hat unter C# eine eigene Bedeutung, Du musst das escapen oder mit @ deaktivieren.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Di 06.09.16 16:17 
Okay, das akzeptiert er nun :)

Aber nun habe ich das Problem, dass er nicht alle Strings ausgibt, sondern nur den ersten, den er findet. Ich muss die CSS Datei auf alle #... parsen und das Ergebnis brauche ich in einer Liste. Wie mache ich das?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 06.09.16 16:21 
Nimm anstatt Match die Mehrzahl: Regex.Matches
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Mi 07.09.16 21:33 
Vielen Dank. Ich bekomme nun eine Liste, wie ich es mir vorstelle. Aber ich habe ein Denkproblem. Ich schreibe ein HTML Programm, was verschiedene Links erstellt und die einzelnen Links in einer CSS Datei verknüpft. Jetzt darf in der CSS Datei die ID (bsp. #link1) nicht zwei mal vorkommen. Sondern dann link2, link3....

Aber dieser Algorithmus funktioniert noch nicht ganz richtig. Erst wird der CSS Text von dem Scintilla als Parameter übergeben [css_maintext]

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
Regex regex = new Regex(@"#(?<id>\w[\w\d]*)");
                foreach (Match match in regex.Matches(css_maintext))
                    MatchResult.Add(match.Value);

                int Indexer = 1;

                foreach(string Try in MatchResult)
                {
                    if (Try == "link" + Indexer.ToString())
                    {
                        Indexer++;
                    }
                    else
                    {
                       // Erstelle CSS Code
                    }
                }


Woran kann es jetzt noch liegen?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Mi 07.09.16 22:55 
Ich habe das Problem nicht ganz durchschaut.

Vielleicht hilft dir aber schon folgender Gedankengang. Was soll passieren und was passiert in deinem Code wenn in MatchResult die Treffer in folgender Reihenfolge stehen

"link3"
"link2"
"link1"

?
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Do 08.09.16 20:33 
Naja in dem Programm soll man verschiedene Links erstellen können. Dafür ist es ja so vorgesehen, dass es in der CSS Datei dann Link1, Link2.... gibt. Wenn der Benutzer nun also die Form öffnet, wird der Text der CSS Datei an die Klasse übergeben. Dann soll geschaut werden, welche Links es schon gibt (bsp: link1, link2 und link3) und dann soll der Algorithmus erkennen: Ah, dann muss ich jz mit link4 weitermachen.

So wie die Controls bsp. auch in VS automatisch durchnummeriert werden. Wie geht das?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Do 08.09.16 20:53 
Die Links könnten in der Datei aber nicht in der Reihenfolgee sein, in der Du sie erwartest.
Du erwarttest in deinem Schnipsel aber, dass die Numerierung aufsteigend ist.

Aber warum zählst Du nicht einfach die Matches? Dann weißt Du auch, wie viele Du hast und wo Du weiter zählen musst.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 08.09.16 22:09 
Das Problem ist für uns nicht wirklich lösbar wir haben keine Ahnung wie du das css erstellst, ob du verhinderst das Leute das Css selbst direkt ändern , ob man in deinem css auch wieder löschen kann u.s.w. Du hast ein selbst geschaffenes Problem mit Css das Css selbst nicht hat und wir wissen nicht viel mehr als das du css benutzt. Ein Verfahren das immer funktionieren könnte ist wenn du einfach neue Namen würfelst und dann prüfst ob das schon in deiner Trefferliste enthalten sind und das halt solange wiederholst bis du auf einen freien Namen triffst. Aber ich habe schon Probleme mir deinen Ansatz grundsätzlich vorzustellen bei den ganzen Möglichkeiten die css an der Stelle hat und die man auch eigentlich für eine sinnvolle Benutzung von Styles primär auch bracht.

Zitat:
Aber warum zählst Du nicht einfach die Matches? Dann weißt Du auch, wie viele Du hast und wo Du weiter zählen musst.


Jetzt nimmst du an das es eine lückenlose Nummerierung hat. Kann sein ist aber eher zu bezweifeln.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Do 08.09.16 22:20 
Zitat:
Jetzt nimmst du an das es eine lückenlose Nummerierung hat. Kann sein ist aber eher zu bezweifeln.


Stimmt

Dann mach ein ein etwas angepasstes RegexPattern, wie das: #(?<id>\w[\w\d]*_(?<number>\d+)) Oder einfacher: #(?<id>link_(?<number>\d+))
Damit kannst Du dann über die Gruppe namens "number" die Nummer abgreifen, zumindest solange davor irgendein Name gefolgt von einem Unterstrich steht.

So kannst Du dann die Nummern der Links abgreifen und als int weiter verarbeiten. So würde ein .Max auf die Nummern reichen und kannst von da aus weiter hoch zählen.


Oder wenn es wirklich nur um die Eindeutigkeit geht und mit den IDs später kein menschliches Wesen direkt arbeiten muss, dann nimm einfach Guids.
ausblenden C#-Quelltext
1:
var uniqueLinkId = "link_" + Guid.NewGuid().ToString("N");					

Das ist dann immer eindeutig.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Fr 09.09.16 19:12 
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
 int Indexer = 0;
                Regex regex = new Regex(@"#(?<id>link_(?<number>\d+))");
                foreach (Match match in regex.Matches(css_maintext))
                {
                    Indexer++;
                    liste.Add(match.ToString());
                }

                StringBuilder builder = new StringBuilder();
                builder.AppendLine("#" + "label_" + Indexer.ToString() + " {");
                builder.AppendLine("\t link:active { color: " + this.tbLinkactive.Text + "; }");
                builder.AppendLine("\t link:hover { color: " + this.tbLinkhover.Text + "; }");
                builder.AppendLine("\t link:visited { color: " + this.tbLinkvisited.Text + "; }");

                if (this.cbLinkunderline.Checked == true)
                    builder.AppendLine("\t a { text-decoration: underline; }");
                else
                    builder.AppendLine("\t a { text-decoration: none; }");

                builder.AppendLine("\t a { color: " + this.tbSchriftfarbe.Text + "; }");
                builder.AppendLine("}");
                GenerierterCSS = builder.ToString();


Jetzt fängt er alle Links mit link_0 an. Es wird nicht durchnummeriert, obwohl in der Datei #link_0 schon vorhanden ist. :autsch:

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Fr 09.09.16 20:07 
Mal kurz eine konzeptuelle Frage: Könntest du nicht css-Klassen nehmen?
Es ist aus HTML/CSS Sicht schon ein bisschen komisch, dass du für jeden Link eine neue ID einführst, und diese dann mit CSS ansprechen willst.

Davon abgesehen scheinst du etwas unüberlegt vorzugehen :P
Hier zum Beispiel:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
foreach (Match match in regex.Matches(css_maintext))
                {
                    Indexer++;
                    liste.Add(match.ToString());
                }

                StringBuilder builder = new StringBuilder();
                builder.AppendLine("#" + "label_" + Indexer.ToString() + " {");


Du speicherst dir erst alle CSS-IDs in eine Liste (gut und richtig). Man sollte annehmen, das passiert mit dem Ziel, später keine doppelten IDs zu generieren. Dann gehst du aber hin und ignoriert die Listeninhalte und guckst nur auf die Länge in "Indexer".
Wenn du schon weist, welche IDs es gibt, dann kannst du doch einfach IDs generieren und direkt prüfen ob es die schon gibt. Und erst, wenn du eine eindeutige gefunden hast, schreibst du die ins CSS
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Fr 09.09.16 20:41 
Ich weiß auch nicht, aber icg glaube ich stehe auf der Leitung.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
int Indexer = 0;
                Regex regex = new Regex(@"#(?<id>link_(?<number>\d+))");
                foreach (Match match in regex.Matches(css_maintext))
                {
                    liste.Add(match.ToString());
                    Indexer++;
                }

                foreach(string s in liste)
                {
                    int i = 0;
                    string checkString = "link_" + i.ToString();
                    if (s != checkString)
                    {
                        // erstelle CSS Script
                    }
                }


Nun wird ja die Liste mit allen Matches befüllt. In der zweiten foreach-Schleife, wird die Liste durchgangen. Dabei wird ein String gebildet, welcher anschließend gecheckt wird, ob es ihn schon gibt. wenn es diesen noch nicht gibt, dann soll er etstellt werden. Aber warum funktioniert das nicht?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 09.09.16 20:54 
Debugge doch deinen Code und schau nach was in s bzw. der gesamten liste steht.
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Fr 09.09.16 21:21 
Ups. In dem Codeausschnitt habe ich i++ vergessen. Ich habe aber bemerkt, dass ich die Variable i an einer falschen Stelle (in der Schleife) als 0 deklariert habe. Was natürlich sinnfrei ist :oops:
Danke, aber jetzt funktioniert es :)

PS: Wenn die CSS Datei leer ist, schreibt er gar nichts in die CSS Datei. Ich denke mal, es liegt daran, dass dann die Liste leer ist und der Code gar nicht erst ausgeführt werden muss. Wie kann ich gucken, ob die Liste von den Items her leer ist. Sowas wie if(...)?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein
Csharp-programmierer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 696
Erhaltene Danke: 10

Windows 8.1
C# (VS 2013)
BeitragVerfasst: Fr 09.09.16 21:40 
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
Regex regex = new Regex(@"#(?<id>link_(?<number>\d+))");
                foreach (Match match in regex.Matches(css_maintext))
                    liste.Add(match.ToString());

                int i = 0;

                if (liste.Capacity == 0)
                {
                   // erstelle CSS Script
                    liste.Add("link_" + i.ToString());
                    i++;
                }

                foreach (string s in liste)
                {
                    string checkString = "link_" + i.ToString();
                    if (s != checkString)
                    {
                        //erstelle CSS Script
                    }
                    i++;
                }


Wenn ich die Methode nun 3 mal aufrufe kommt das raus:
1
0
1
2

Aber ich sage ja in der ListenFoream eindeutig, dass wenn s != checkedString ist, dann soll er es machen und nicht wenn s == checkedString ist. Woran liegt es jetzt noch?

_________________
"Wer keinen Sinn im Leben sieht, ist nicht nur unglücklich, sondern kaum lebensfähig" - Albert Einstein