Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Prüfen, ob ein String eine Url (für eine Webseite) ist
Fummelchen
myCSharp.de - Member



Dabei seit:
Beiträge: 2

Themenstarter:

Prüfen, ob ein String eine Url (für eine Webseite) ist

beantworten | zitieren | melden

Ich möchte gerne nach dem Click-Event überprüfen ob in der Textbox die Kriterien einer Webaddresse enthalten sind.

http://www.google.com

wie stelle ich das am besten an?
private Nachricht | Beiträge des Benutzers
[email protected]
myCSharp.de - Member



Dabei seit:
Beiträge: 407

beantworten | zitieren | melden

Hi Fummelchen,

sowas geht am besten mit einem regulären Ausdruck.

lg
private Nachricht | Beiträge des Benutzers
uNki
myCSharp.de - Member



Dabei seit:
Beiträge: 61

beantworten | zitieren | melden

du kannst ja auch für eine schnelle lösung die

TextBox1.Text.StartsWith("http://www.") --> bool

und

TextBox1.Text.EndsWith(".com") --> bool

funktionen verwenden.
private Nachricht | Beiträge des Benutzers
Darth Maim
myCSharp.de - Member



Dabei seit:
Beiträge: 230

beantworten | zitieren | melden

Das funktioniert so vorne und hinten nicht...

Was passiert wenn man das http weglässt, oder https hat, statt www eine Subdomain, eine andere TLD als .com, eventuell noch einen Pfad hinten dran? Die StartsWith/EndsWith Variante funktioniert vllt. in 1% aller Fälle.

Darth Maim
private Nachricht | Beiträge des Benutzers
Fummelchen
myCSharp.de - Member



Dabei seit:
Beiträge: 2

Themenstarter:

beantworten | zitieren | melden

nene, [email protected] hat's schon in die richtige Richtung gebracht. -> Regular Expressions ist hier eindeutig die beste Lösung.

Momentan sieht mein Muster so aus:

Regex RgxUrl = new Regex(@"^(http|https)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*[^\.\,\)\(\s]$");
lässt aber noch so einige Fehler zu.

Experimentiere gerade ein wenig mit der Klasse "System.Globalization.CompareInfo" und versuche Fehleingaben so zu filtern und ggf zu berichtigen.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Fummelchen,

dafür sollte es jede Menge fertiger Pattern geben. Einen guten zu finden, dürfte allerdings nicht einfacher sein, als einen guten zu schreiben. :-)

Um einen guten zu schreiben, muss man natürlich erstmal die Regeln für Domainnamen kennen. Dazu sollte man am besten in die entsprechende RFC schauen. So sind Toplevel-Domains schon lange nicht mehr auf zwei oder drei Stellen begrenzt (z.B. .info, .name) und gerade in Zukunft werden noch viele längere TLDs kommen. Auch sind mittlerweile Umlaute u.ä. erlaubt (z.B. www.äöüÄÖÜ.de). Es ist eh die Frage, wie strikt man prüfen sollte, gerade mit dem Blick, dass in Zukunft vielleicht noch weitere Lockerungen vorgenommen werden.

Ich denke, wenn auf den zu prüfenden String ^https?://[^.]+\..+/ zutrifft, kann man davon ausgehen, dass es sich um eine Url handelt. Ob sie gültig ist, kann man per Regex eh nicht abschließend prüfen, denn selbst wenn das Format stimmt, bedeutet das ja nicht, dass die Domain existiert.

herbivore

PS: Für die Prüfung von E-Mail-Adressen werden in How to Find or Validate an Email Address einige interessante Überlegungen angestellt, die man auch auf URLs übertragen kann.
private Nachricht | Beiträge des Benutzers
ujr
myCSharp.de - Experte



Dabei seit:
Beiträge: 1770

beantworten | zitieren | melden

Hallo,

man kann es sich auch ganz einfach machen und die Fähigkeiten der Uri-Klasse benutzen.
private Nachricht | Beiträge des Benutzers
uNki
myCSharp.de - Member



Dabei seit:
Beiträge: 61

beantworten | zitieren | melden

Zitat
Was passiert wenn man das http weglässt, oder https hat, statt www eine Subdomain, eine andere TLD als .com, eventuell noch einen Pfad hinten dran? Die StartsWith/EndsWith Variante funktioniert vllt. in 1% aller Fälle.

ja, natürlich reicht der code oben allein noch nicht aus. da sollte man schon noch eine ordentliche fallunterscheidung einbauen. dann kommst du auch wesentlich weiter als "1%" ;) kommst genauso weit wie mit regular expressions.

ob ich nun den string mit regular expressions oder mit "normalen" string-operationen überprüfe, ist doch vielmehr sache des geschmacks, oder gibt es da signifikante performanceunterschiede?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo uNki,

es gibt signifikante Unterschiede in der Länge des erforderlichen Quellcodes. Gerade wenn man alle möglichen Varianten mit normalen String-Operationen ausprogrammiert, wird es sehr länglich. In Regex erfordert das dagegen oft nur ein zusätzliches Zeichen, z.B. ? oder * oder |. Insofern ist Regex die deutlich bessere Wahl gegenüber StartsWith & Co.

herbivore

EDIT: Wobei die Länge des Quellcodes natürlich nicht per se etwas über seine Güte sagt. Allerdings ist mit normalen String-Operationen ausprogrammierter Code nicht nur länglich, sondern typischerweise auch sehr unübersichtlich und damit normalerweise schlechter zu lesen und schwerer zu verstehen, als der gleichwertige Regex-Pattern.
private Nachricht | Beiträge des Benutzers
uNki
myCSharp.de - Member



Dabei seit:
Beiträge: 61

beantworten | zitieren | melden

was mich dabei noch interessieren würde: werden regular expressions vom compiler auch schneller "abgearbeitet" als "normale" string-operationen? oder ist es so, dass regular expressions im hintergrund auch nur durch normale string-operationen ausgeführt werden?
(wie z.b. eine foreach-schleife, die im hintergrund ja auch nur wie eine gewöhnliche for-schleife behandelt wird - wenn ich mich nicht irre)

danke
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von uNki am .

Moderationshinweis von herbivore (07.01.2012 - 13:31:46):

Naheliegenderweise arbeitet Regex intern nicht mit Voodoo. Also natürlich letzteres. Anderseits werden dabei teilweise Optimierungen verwenden, auf die der Durchschnittsprogrammierer nicht so leicht kommt. Was schneller ist, hängt immer von der konkreten Situation und dem konkreten Pattern ab. Mögliche Unterschiede in der Ausführungsgeschwindigkeit sind aber auf heutigen Rechnern so gut wie nie relevant.

BTW: foreach wird intern in eine while-Schleife (innerhalb eines try-finally) umgesetzt, siehe C# Language Specification: 8.8.4 The foreach statement, siehe auch foreach oder for? was ist schneller? Ist die Reihenfolge festgelegt?.

Back2Topic

private Nachricht | Beiträge des Benutzers
winSharp93
myCSharp.de - Experte

Avatar #avatar-2918.png


Dabei seit:
Beiträge: 6155
Herkunft: Stuttgart

beantworten | zitieren | melden

Zitat von ujr
es sich auch ganz einfach machen und die Fähigkeiten der Uri-Klasse benutzen.
Ja - aber das wäre wohl zu einfach...
private Nachricht | Beiträge des Benutzers
talla
myCSharp.de - Experte

Avatar #avatar-3214.jpg


Dabei seit:
Beiträge: 7290
Herkunft: Esslingen

beantworten | zitieren | melden

Kleine Anmerkung: URL und URI sind nicht das gleiche. Nichtsdestotrotz lässt sich natürlich durch Verwendung der URI Klasse prüfen ob die URL gültig ist.
Baka wa shinanakya naoranai.

Mein XING Profil.
private Nachricht | Beiträge des Benutzers
Coder007
myCSharp.de - Member



Dabei seit:
Beiträge: 1249

beantworten | zitieren | melden

Ich würde an der Stelle nicht zu viel Aufwand treiben. Ich kann dir sagen, wie das in subversion gelöst ist (die müssen an zig Stellen entscheiden, ob ein übergebener Pfad eine Url oder ein lokaler Pfad ist). Die prüfen im Endeffekt nur, ob der String mit ein paar Buchstaben + "://" anfängt. Das hat natürlich gewisse Einschränkungen und mag in deinem Fall vielleicht gar nicht reichen, aber etwas ähnliches würde ich auch bauen.
private Nachricht | Beiträge des Benutzers
Lynix
myCSharp.de - Member



Dabei seit:
Beiträge: 670
Herkunft: Saarland

beantworten | zitieren | melden

Zitat von herbivore
es gibt signifikante Unterschiede in der Länge des erforderlichen Quellcodes. Gerade wenn man alle möglichen Varianten mit normalen String-Operationen ausprogrammiert, wird es sehr länglich. In Regex erfordert das dagegen oft nur ein zusätzliches Zeichen, z.B. ? oder * oder |. Insofern ist Regex die deutlich bessere Wahl gegenüber StartsWith & Co.

Ein längerer Code ist nicht automatisch ein schlechterer Code, gerade im Hinblick auf die Lesbarkeit. Wenn ich irgendwo RegExp sehe kommt mir das Grausen, das erinnert mich immer an die kryptischen Perl-Scripts aus längst vergangenen Zeiten. Lambda Expressions sind genauso ein Murks, der nicht zur Lesbarkeit beigetragen hat. Ist aber nur meine Meinung...
"It is not wise to be wise" - Sun Tzu

Moderationshinweis von herbivore (09.01.2012 - 18:12:29):

Korrekt, längerer Code ist nicht automatisch schlechter, und es stimmt, dass (komplexere) Regex-Ausdrücke nicht so schön zu lesen sind, aber ein als normaler Code "ausprogrammierer" Regex Ausdruck ist typischerweise deutlich schlechter zu lesen und schwerer zu verstehen, als der Regex-Ausdruck.

Aber bitte nochmal: Back2Topic!

private Nachricht | Beiträge des Benutzers