C# Link aus FF per Drag&Drop in WinForm, Linktext leichter erreichbar?

AP Nova

Commander
Registriert
Juni 2008
Beiträge
2.256
Im Rahmen eines kleinen Programms, an dem ich gerade sitze, würde ich gerne einen Link per Drag&Drop aus Firefox in meine WinForm kopieren. Das klappt auch einwandfrei mit der URL, aber damit man weiß, was das überhaupt für ein Link ist, hätte ich gerne, dass eine eventuell vorhandene Linkbeschreibung ebenfalls kopiert wird. Also wenn ich beispielsweise irgendwo Folgendes per Drag&Drop kopieren wollte, hätte ich gerne im Programm nicht nur "www.google.com" verfügbar, sondern auch "Google": Google

Ich bin mittlerweile so weit, dass ich rausfinden konnte, welche Objekttypen im rübergezogenen Objekt enthalten sind:
Code:
string[] test1 = e.Data.GetFormats()
Das liefert dann die folgenden Elemente:
[0] "text/x-moz-url" string
[1] "FileGroupDescriptor" string
[2] "FileGroupDescriptorW" string
[3] "FileContents" string
[4] "UniformResourceLocator" string
[5] "UniformResourceLocatorW" string
[6] "text/x-moz-url-data" string
[7] "text/x-moz-url-desc" string
[8] "text/uri-list" string
[9] "text/_moz_htmlcontext" string
[10] "text/_moz_htmlinfo" string
[11] "text/html" string
[12] "HTML Format" string
[13] "System.String" string
[14] "UnicodeText" string
[15] "Text" string
[16] "DragImageBits" string
[17] "DragContext" string

Allerdings kann ich nur Element 12 bis 15 in einen String umwandeln, wobei 3 Stück einfach die URL beinhalten, 12 beinhaltet anscheinend den HTML-Code, der den Link letztendlich darstellen lässt. Beispiel an Hand des obigen Links:
"Version:0.9\r\nStartHTML:00000174\r\nEndHTML:00000318\r\nStartFragment:00000208\r\nEndFragment:00000282\r\nSourceURL:https://www.computerbase.de/forum/newthread.php?do=postthread&f=39\r\n<html><body>\r\n<!--StartFragment--><a href=\"http://www.google.com/\" target=\"_blank\" rel=\"nofollow\">Google</a><!--EndFragment-->\r\n</body>\r\n</html>\0"
Muss ich jetzt wirklich diesen Link mit den üblichen Stringbearbeitungsmethoden zerlegen, um an den gewünschten Teil zu kommen, oder ist genau das vielleicht doch noch in irgendeinem der übrigen Elemente gespeichert und einfacher zu erreichen?

Danke für eure Hilfe
 
Zwar nicht C#, aber hatte in PHP letztens ein ähnliches Problem. Abhilfe hat dann ein HTML Parser gebracht. Mit dem kannst dann einfach den <a> Tag herauspicken und dir den "Inhalt" geben lassen, also den eingeschlossenen Text.
Wenn die Links immer so aufgebaut sind, machts sicher auch schon ein kleiner RegEs Ausdruck.
 
Also allgemein ist meine Idee halt, dass man öfter mal zum Beispiel auf Youtube viele kleine Videos findet, die man gucken will, aber dann hat man nur zwei Optionen: Entweder für jedes einen Tab öffnen und offen halten, bis man es geguckt hat (was unübersichtlich und umständlich ist) oder die URL irgendwo zwischenspeichern. Es wäre einfacher, könnte man dann einfach ein Video, das man noch gucken will, schnell irgendwohin rüberziehen und später von dort mit einem einfachen Klick öffnen.
Den "HTML-Zerleger" dann entsprechend auf "normale" Links mit nur Text als Linkbeschreibung oder nur auf Links von Youtube zuzuschneiden ist nicht das große Problem, da muss man nur einmal den Aufbau des gesamten Strings anschauen und überlegen, wie man den passend zerlegen kann, das ist dann in zwei Zeilen gemacht.

Mein ursprünglicher Gedanke bzw. meine ursprüngliche Hoffnung war einfach, dass genau das ja vielleicht schon im Objekt enthalten ist und man so ganz einfach darauf zugreifen könnte, aber anscheinend ist das ja nicht so. (Oder falls das doch in irgendeinem der übrigen 14 Elemente enthalten sein sollte, ist der Zugriff darauf wahrscheinlich umständlicher als alles andere...)

Aber trotzdem danke
 
Wenn Element 12 immer ähnlich ist wie oben gezeigt, dann lässt sich das mit einem regulären Ausdruck schnell machen.

Element 12 als String und den RegEx drauf anwenden.

Kurze Google Suche für den Ausdruck: "<a[^>]*>(.*?)</a>".

Hab ich jetzt nicht getestet, aber der sollte dir den Text zwischen dem <a> Tag mit der richtigen C# Funktion liefern.
Einfach mal die C# RegEx Funktionen anschauen. In Java wärs ein 3 Zeiler ;)


Nachtrag
hab mal weiter gesucht, weil ich C# auch bald habe
Sollte so in die Richtung gehen:
Code:
 public string getLinkName(string html) {
  Regex r = new Regex("<a[^>]*>(.*?)</a>");
  Match m = r.Match(html);

  if (m.Success){
    return match.Groups[1].Value;
  }
  return;
}
 
Zuletzt bearbeitet:
Danke shuffl3, vielleicht gucke ich mir RegEx im Rahmen des hierfür nötigen mal an. Ich hatte zwar schon von RegEx an sich gehört, wusste aber nicht, dass das mit C# auch umsetzbar ist und kam mit den "Standardmitteln" zum Arbeiten mit Strings bisher ganz gut zurecht, aber wenn ich jetzt sowieso ein Beispiel habe, könnte ich ja zumindest im Rahmen dessen mal versuchen, das Arbeiten mit RegEx in C# zu verstehen.

Sehe ich das richtig, dass dein RegEx-Ausdruck Folgendes bedeutet?
-Es fängt an mit "<a"
-Dann jeder Charakter, der nicht ">" ist, beliebig oft
-Dann ">"
-Dann beliebig oft jedes beliebige Zeichen? Aber wofür das "?" hinter ".*" und wofür die Klammern?
-Am Ende steht steht dann "</a>"

Ich konnte jetzt zumindest mal auch mit RegEx für einen Link von Youtube eine entsprechende Methode schreiben bzw. die beiden Ausdrücke so in eine Funktion packen, dass die Funktion unabhängig davon, ob das nun aus den empfohlenen Videos von Youtube stammt oder ein "normaler" Link (im Sinn von nur Text) ist, das Gewünschte liefert:
Code:
        public string getLinkName(string html)
        {
            Regex standardLink = new Regex("<a[^>]*>(.*?)</a>"), ytLink = new Regex("\"title\" title=\"(.*?)\">");
            Match m;
            if ((m = ytLink.Match(html)).Success)
                return m.Groups[1].Value;
            else
                if ((m = standardLink.Match(html)).Success)
                    return m.Groups[1].Value;
            return null;
        }
 
Zuletzt bearbeitet:
Wie gesagt, ich hab den Ausdruck auch nur eben von Google.

Allgemein sagt das ? aus, dass eine Zeichenfolge ein- oder keinmal vorkommt.

Na dann sollte dein Problem ja gelöst sein :D

Nachtrag

mit | kannst du beide Ausdrücke zu einem zusammenfassen. | bedeutet oder, also Ausdruck1 | Ausdruck 2
 
Zuletzt bearbeitet:
shuffl3 schrieb:
Allgemein sagt das ? aus, dass eine Zeichenfolge ein- oder keinmal vorkommt.
So weit hatte ich das verstanden. Aber ich verstehe es in Verbindung mit ".*" nicht, weil das heißt doch schon, dass ein beliebiges Zeichen beliebig oft vorkommt, oder nicht? Das "?" dahinter wirkt dann überflüssig für mich. Oder braucht man das, um zu sagen, welchen Text man letztendlich wirklich erhalten will? Weil das "</a>" zum Beispiel ist ja letztendlich auch im RegEx und im zu vergleichenden Text enthalten, wird aber letztlich nicht ausgegeben.
 
.*? deshalb, damit die Geschichte nicht über das Ziel hinausschießt. Wüsste auch nicht wie ich es korrekt erklären könnte, man kann aber mit einem Test einfach nachschauen was passiert, wenn das ? fehlt :evillol:.

Dann würde ich dir ein Regex mit "lookbehind" und "-ahead" empfehlen, dann verschwindet der Zugriff auf die Groups.
Ergo folgendes Regex @"(?<=<a[^>]*>).*?(?=</a>)"

Beim zweiten bin mich mir nicht ganz sicher, was du gerne finden möchtest, habe das mal frei gelassen.

Code:
public string getLinkName(string html)
{
    Regex standardLink = new Regex(@"(?<=<a[^>]*>).*?(?=</a>)"), 
    ytLink = new Regex("nochFrei");
    if (standardLink.IsMatch(html))
    {
         return standardLink.Match(html).Value;
    }
    else if (ytLink.IsMatch(html))
    {
        return ytLink.Matches(html).Value;
    }
  return null;
}

#Edit: .* findet die vorangehende Zeichenfolge '.' (was für jedes Zeichen steht) so oft wie möglich, d.h. </a> kann dort auch drinnen vorkommen, solange ganz am Ende auch noch einmal </a> zu finden ist. Er sucht also die längst möglichste Übereinstimmung. Durch das ? wird der Punkt limitiert, so dass er die kürzest mögliche Übereinstimmung findet.
 
Zuletzt bearbeitet: (Nochmal ergänzend :))
Wenn man * und ? .. einzeln betrachtet sind es gierige Quantifikatoren. Wenn man einen Quantifikator mit einem ? kombiniert wird er zu einem trägen Quantifikator. *? ist also ein Quantifikator und nicht zwei. Das hat was mit der internen Mustererkennung zu tun. Kurz gesagt findet *? die minimale Anzahl von Übereinstimmungen.

Nachtrag
Da war PapstRatze wohl schneller :D
PapstRatze schrieb:
.*? deshalb, damit die Geschichte nicht über das Ziel hinausschießt
genau .* findet die maximale Anzahl von Übereinstimmungen.

ps: Google weiß echt ne Menge, wusste ich vorher auch nicht :hammer_alt:
 
Zuletzt bearbeitet:
Vielen Dank für eure Hilfe!

Mein Programm ist so weit auch fertig und kann zumindest mal mit erwähnten "Standardlinks" und den empfohlenen Videos auf Youtube umgehen, der Einfachheit halber und um es selbst besser nachvollziehen zu können habe ich es jetzt bei den RegEx-Ausdrücken belassen, die ich oben gepostet habe.

(Falls wen interessiert, was das Programm jetzt genau macht: Wie erwähnt kann man per Drag&Drop einen Link in das Fenster ziehen, der wird dann in einer Listbox gespeichert. Klickt man mit der linken Maustaste, wird der Link ganz normal geöffnet und der Eintrag gelöscht, bei einem Klick mit der mittleren Maustaste wird der Link geöffnet aber der Eintrag bleibt erhalten und bei einem Klick mit der rechten Maustaste wird einfach nur der Eintrag gelöscht. Dazu hat man die Wahl, entweder die Links oder den Text dazu in der Listbox anzeigen zu lassen. Und falls man dann doch mal keine Lust hat, die Links jetzt direkt anzuschauen, habe ich noch eine Speicher- und Lademöglichkeit für die Listen eingebaut. Falls Interesse besteht, kann ich das Projekt/den Code hier posten)
 
Zurück
Oben