Regex-Magie

Moin!

Ich hoffe, hier kennt sich jemand sehr gut mit Regexen aus, bin grad zu faul, mich in nem Entwicklerforum anzumelden. :ugly:

Ich versuche URIs in Fließtext abzufangen. Derzeitiger Stand:

((?:(?:https?:\/\/)|(?:www))(?:[a-zA-Z0-9\~\!\@\#\$\%\^\&\*_\-\=\+\\\/\?\.\:\;\'\,]+))

Klappt soweit ganz gut, außer, wenn nach dem letzten Zeichen der URI noch ein Satzzeichen (,;.:) steht, das wird dann auch mit markiert, obwohl es das idealerweise nicht sollte.

Theoretisch können nach der URI folgende Zeichen/Situationen auftreten:
http://www.bla.de/bla.pdf[,;.:\!\?\)\]\}\>\"\']*\s?$ ← evtl. ein Satzzeichen oder eine schließende Klammer oder Anführungszeichen und/oder evtl. ein Leerzeichen und/oder evtl. Zeilenende

oder anschaulicher:

  1. http://www.bla.de/bla.pdf$
  2. http://www.bla.de/bla.pdf.$
  3. http://www.bla.de/bla.pdf. $
  4. http://www.bla.de/bla.pdf. bla
  5. http://www.bla.de/bla.pdf) bla
  6. http://www.bla.de/bla.pdf.) bla
  7. http://www.bla.de/bla.pdf). Bla

wobei „.“ exemplarisch für alle möglichen Satzzeichen steht, „)“ für alle möglichen Klammern.

Die bisherige Abfrage matcht 1., 5. und 7. korrekt, bei den anderen wird der Punkt am Ende mitmarkiert. Kann ich das in einer einzigen Abfrage vermeiden? Ich habe schon diverse positive Look aheads versucht, aber entweder wird wieder das Satzzeichen markiert, oder URIs, auf die ein Leerzeichen oder das Zeilenende folgt, werden nicht gematcht.

Auf den entscheidenden Trick/die entscheidende Formulierung bin ich noch nicht gekommen. :confused:

Gut zum schnellen Testen: https://regex101.com/

Als ich ein ähnliches Problem hatte, hat mir das geholfen, musste nur ein wenig anpassen: https://stackoverflow.com/questions/16463666/javascript-regex-to-match-fully-qualified-domain-name-without-protocol-optiona

Ich bin mir auch nicht sicher ob ~, !, # und all die Zeichen die du erlaubst gültige Zeichen sind.

Bin jetzt auch zu faul dir direkt die Lösung zu geben jedoch würde ich den Teil

in einzelne Teile unterteilen wie:
(([a-zA-Z0-9]+[\.]*[a-zA-Z0-9]+)+\/([a-zA-Z0-9]+[\.]*[a-zA-Z0-9]+)+)+
ob das Beispiel wirklich funktionstüchtig ist weis ich nicht, hab es nur eben so hingetippt aber vielleicht erkennst du was ich meine, eine beliebige Zahlen-/Buchstabenkombination eventuell getrennt durch einen Punkt getrennt, beliebig oft wiederholt gefolgt von einem / mit wieder einer beliebigen Zahlen-/Buchstabenkombination und das alles mindestens einmal. Besser noch wenn du die Anzahl an Wiederholungen kennst das + durch {<mindest Anzahl>, <maximal Anzahl>} ersetzen

1 „Gefällt mir“

Zum Großteil ja, aber ob die URI valide ist oder nicht, ist mir eigentlich egal, darum das wahrscheinlich zu große Spektrum. Der Autor hat im eigenen Interesse dafür Sorge zu tragen, dass die Adresse korrekt ist. :grin:

Mittlerweile hab ich aber was gefunden, und ich vergesse das immer wieder: \b

((?:(?:https?:\/\/)|(?:www))(?:[a-zA-Z0-9\~\!\@\#\$\%\^\&amp;\*_\-\=\+\\\/\?\.\:\;\'\,]+))(?=\b) ← hier am Ende als positiver Look ahead. Damit matcht das Ganze nur bis zur Wortgrenze. Zwar werden so etwaige Sonderzeichen am Ende nicht mehr getroffen, aber ob da überhaupt andere als „/“ erlaubt sind, weiß ich nicht. Ist auf jeden Fall weniger tragisch, als die mitgematchten Satzzeichen. :slight_smile:

Jedenfalls Danke für den Input!

2 „Gefällt mir“