Diese Woche war ich ein bißchen ungeduldig und wollte das mit den *regular expressions* endlich zu Ende bringen. Was heißt zu Ende, bei sowas lernt eine ja nie aus. Aber zumindest soweit, daß ich mein kleines [Testprojekt](http://www.camilla-kutzner.de/blog/2014/01/regular-expressions-was-ist-denn-das-schon-wieder/) mal abschließen konnte, wollte ich kommen.
Mein Testszenario ist insofern etwas unrealistisch, als alle Zeilen konsistent mit http://
begannen – es fehlte nirgends, und es kam auch kein https://
vor. Großbuchstaben waren nicht enthalten. Außerdem habe ich mit einem eher kleinen Set von möglichen Domainendungen, die ich gerade aus dem Kopf noch wußte, gearbeitet.
Ich wiederhole zur Bequemlichkeit mein Test-Szenario:
Eine Liste von Domains, etwa [diese](http://pastebin.com/W3eS82Vq), soll in das Format „domainname.tld“ überführt werden.
### Meine Lösung
In meinem Texteditor gedit mit dem Plugin [Advanced Find & Replace](http://code.google.com/p/advanced-find/) brauchte ich nur eine Zeile:
,^http://(.*\.)?([A-Za-z0-9-]+\.)(at|de|com|co.uk|net|org|fr|it|es|pl|dk|se|no|edu).*,\2\3/,
Hier einmal etwas erläutert:
Suchstring ^http:// # beginnt mit http:// (.*\.)? # Gruppe 1: optionale Gruppe (markiert durch das Fragezeichen), die beliebige Charaktere enthält und mit einem Punkt abschließt ([A-Za-z0-9-]+\.) # Gruppe 2: Teil des Domainnamens: Buchstaben, Ziffern und Bindestrich, einmal oder mehrmals, abgeschlossen durch einen Punkt. (at|de|com|co.uk|net|org|fr|it|es|pl|dk|se|no|edu) # Gruppe 3: Domainendungen, mit einem Alternator getrennt. .* # beliebige Zeichen, die nach der Domainendung noch kommen
Ersetzungsstring: \2 # Gruppe 2 \3 # Gruppe 3
In vim brauchte ich 2 Ausdrücke, da die regex-Syntax in vim etwas anders ist und ich auf den ersten Anhieb keine Möglichkeit fand, einen Ausdruck optional zu machen:
:%s/http:\/\/*\([a-z0-9-\.]\+\.\)\(at\|de\|com\|co.uk\|net\|org\|fr\|it\|es\|pl\|dk\|se\|no\|edu\).*/\1\2
Damit werden die Zeichen nach der Domainendung sowie das http entfernt.
Um dann aber Zeilen wie blog.example.org oder foo.bar.org auf ihre nackten Domainnamen zu reduzieren, brauchte ich eine zweite Regex:
:%s/\([a-z0-9-]\+\.\)\([a-z0-9-]\+\.\)\(at\|de\|com\|co.uk\|net\|org\|fr\|it\|es\|pl\|dk\|se\|no\|edu\)/\2\3
Damit klappte es dann, und ich hatte die Domains in der gewünschten Form vorliegen.
Habt Ihr Vorschläge, wie das Ganze noch eleganter zu lösen wäre? Oder Tips, wie ich eine schönere Lösung in vim hinbekommen könnte?