Beat: RegEx-Problem

Beitrag lesen

(https?://)?(www.)?[\da-zA-ZÄÖÜ.@:]*.[a-zA-Z]{2,4}[\da-zA-ZÄÖÜ.!#$%&'()\*+,/:;=?@[]]

ist das so in Ordnung? Oder haltet ihr diese RegEx für falsch?

(https?://)?

Du meinst, du akzeptierst auch relative Pfade?

(www.)?

und was ist mit
subdom.example.org?

[\da-zA-ZÄÖÜ.@:]*

Eine 2nd level Domain besteht aus mindestens einem Zeichen
Entweder du akzeptierst nur [A-Za-z0-9_]
oder du akzeptierst alle Zeichen ausser [^/.]
.
[a-zA-Z]{2,4}

und was ist mit
   .museum
etc?
[a-zA-Z]{2,6}
wäre angemessener für eine TLD

dann haben wir an diesem Punkt aber auch IPs
123.156.1.1
eventuell mit Port
123.156.1.1:8080

[\da-zA-ZÄÖÜ.!#$%&'()\*+,/:;=?@[]]

Dieser Salat steht wohl für Pfad, Querystring und Fragment

Ich würde einen anderen Ansatz nehmen

https?://[^/\s]+

Dies umfasst alles bis zum beginn des Pfades.
Wesentlich ist, dass eine Authority keinen Whitespace \s und keinen / enthalten darf. Eventuell auch eine Reihe anderer Zeichen nicht.
Wir können die erlaubten zeichen auch sumarisch bezeichnen

[A-Za-z0-9_.:%-] das @ lasse ich mal weg in der Annahme, dass User@Password nicht gesendet wird

https?://[A-Za-z0-9_.:%-]+

Ein Pfad ist optional und hat optional eine Pfadangabe mit Query und Fragment.

(/(pfad+query+fragment)?)?

Ein Pfad ist simpel ausgedrückt alles, was weder Whitespace noch ein ? noch ein # ist.

(/([^\s#?]+)?(query+fragment)?)?

Ein query ist etwas komplexer, weil da verschiedene Delimiter erlaubt sind.
Aber wir können vorwärtsschauend sagen, dass ein Querystring alles ausser Whitespace und # ist, aber mit ? beginnt

(/([^\s#?]+)?(?[^\s#]+?)?(fragment)?)?

Ein Fragment beginnt mit # und hat dann nonwhitespace zur Folge. HTML stellt an ein Fragment zusätzliche Anforderungen, die uns aber hier egal sein können

(/([^\s#?]+)?(?[^\s#]+?)?(#[^\s]+)?)?

Das ganze ist nun:
https?://[A-Za-z0-9_.:%-]+(/([^\s#?]+)?(?[^\s#]+?)?(#[^\s]+)?)?

nun haben wir aber ein problem meit denen Delimiter [ ], welche im Pattern nicht vorkommen dürfen. Entweder wie integrieren diese zeichen als verbotene Zeichenklasse:

https?://[A-Za-z0-9_.:%-]+(/([^\s#?[]]+)?(?[^\s#[]])?(#[^\s[]]+)?)?

oder wir verwenden non greedy Quantifier
+?  *?  ??
https?://[A-Za-z0-9_.:%-]+?(/([^\s#?]+?)?(?[^\s#]+?)?(#[^\s]+?)?)?
wobei wir nun die äussere Schicht ergänzen können und gleichzeitig das zu suchende matchen
<(matche dies)>

[link=(https?://[A-Za-z0-9_.:%-]+?(/([^\s#?]+?)?(?[^\s#]+?)?(#[^\s]+?)?)?]

Jetzt noch das optionale label.
Dieses beginnt mit @title= und hat irgend etwas 'non greedy'
(@title=.+?)?

zusammen

[link=(https?://[A-Za-z0-9_.:%-]+?(/([^\s#?]+?)?(?[^\s#]+?)?(#[^\s]+?)?)?(@title=.+?)?]

Eine Perl version zur besseren Lesbarkeit

m/[
  link=
  (
    https?://
    [A-Za-z0-9_.:%-]+?
    (/
      ([^\s#?]+?)?
      (?[^\s#]+?)?
      (#[^\s]+?)?
    )?
    (@title=.+?)?
  ]/x

Und nun matchen:
() speichert in $1 - $9
(?:) speichert nicht
Ich speichere die Url und das label separat, vermeide aber das Speichern aller sepraten url teile

m/[
  link=
  (
    https?://
    [A-Za-z0-9_.:%-]+?
    (?:/
      (?:[^\s#?]+?)?
      (?:?[^\s#]+?)?
      (?:#[^\s]+?)?
    )?
    (@title=.+?)?
  ]/<a href="$1">$2</a>/x

Was aber wenn kein Label angegeben ist?
ich nehme s///ex (evaluiere einmal)

m/[
  link=
  (
    https?://
    [A-Za-z0-9_.:%-]+?
    (?:/
      (?:[^\s#?]+?)?
      (?:?[^\s#]+?)?
      (?:#[^\s]+?)?
    )?
    (@title=.+?)?
  ]/'<a href="'.$1.'">'. $2|| $1 . '</a>'/ex

Wenn jetzt die url sehr lange ist, kann es sein, dass diese lange url bei fehlendem Label das layout zerstört. In diesem Falle möchte ich nur die Domain ohne Pfad etc. Die vollkommene url soll aber in ein title attribut geschrieben werden.

Zu diesem zweck muss ich eine untergruppe speichern:
(https?://domain)

m/[
  link=
  (
    (
      https?://
      [A-Za-z0-9_.:%-]+?
    )
    (?:/
      (?:[^\s#?]+?)?
      (?:?[^\s#]+?)?
      (?:#[^\s]+?)?
    )?
    (@title=.+?)?
  ]/'<a href="'.$1.'" title="'. $1 .'">'. $3 || $2 . '</a>'/ex

So geht das in Perl. Umsetzung nach C# als Übung.
Ich weiss nicht, ob C# die nicht speichernden (?:) versteht.
Den Ersetzungsteil musst du sicher selbst schreiben.

mfg Beat

--
Woran ich arbeite:
X-Torah
><o(((°>           ><o(((°>
   <°)))o><                     ><o(((°>o