512 Stimmen

Nicht gieriger (zurückhaltender) Regex-Abgleich in sed?

Ich versuche, sed zu verwenden, um Zeilen von URLs zu bereinigen, um nur die Domain zu extrahieren.

Also von:

http://www.suepearson.co.uk/product/174/71/3816/

Ich will:

http://www.suepearson.co.uk/

(entweder mit oder ohne den abschließenden Schrägstrich, es spielt keine Rolle)

Ich habe es versucht:

 sed 's|\(http:\/\/.*?\/\).*|\1|'

und (unter Auslassung des nicht-gierigen Quantors)

sed 's|\(http:\/\/.*\?\/\).*|\1|'

aber ich scheine den nicht-gierigen Quantifizierer nicht zu bekommen ( ? ), um zu funktionieren, so dass am Ende immer die ganze Zeichenfolge übereinstimmt.

68 Stimmen

Eine Randbemerkung: Wenn Sie Ihre Regexe mit "|" abgrenzen, brauchen Sie die "/"s nicht zu escapen. Tatsächlich grenzen die meisten Leute mit "|" anstelle von "/" ab, um die "Zäune" zu vermeiden.

15 Stimmen

@AttishOculus Das erste Zeichen nach dem 's' in einem Ersatzausdruck in sed ist das Trennzeichen. Daher funktionieren auch 's^foo^bar^' oder 's!foo!bar!'

1 Stimmen

Für erweiterte Regex, verwenden Sie sed -E 's... . Dennoch, kein unwilliger Betreiber.

5voto

peterh Punkte 16923

sed hat sicherlich seine Berechtigung, aber das hier gehört nicht dazu!

Wie Dee bereits erwähnt hat: Verwenden Sie einfach cut . In diesem Fall ist es viel einfacher und viel sicherer. Hier ist ein Beispiel, in dem wir verschiedene Komponenten aus der URL mit der Bash-Syntax extrahieren:

url="http://www.suepearson.co.uk/product/174/71/3816/"

protocol=$(echo "$url" | cut -d':' -f1)
host=$(echo "$url" | cut -d'/' -f3)
urlhost=$(echo "$url" | cut -d'/' -f1-3)
urlpath=$(echo "$url" | cut -d'/' -f4-)

gibt Ihnen:

protocol = "http"
host = "www.suepearson.co.uk"
urlhost = "http://www.suepearson.co.uk"
urlpath = "product/174/71/3816/"

Wie Sie sehen können, ist dies ein sehr viel flexiblerer Ansatz.

(alle Angaben zu Dee)

4voto

Lucero Punkte 57715
sed 's|(http:\/\/[^\/]+\/).*|\1|'

3 Stimmen

Wenn Sie "|" als Trennzeichen verwenden, brauchen Sie "/" nicht zu escapen.

4voto

stepancheg Punkte 4124

Sed -E interpretiert reguläre Ausdrücke als erweiterte (moderne) reguläre Ausdrücke

Aktualisierung: -E unter MacOS X, -r in GNU sed.

4 Stimmen

Nein, tut es nicht... Zumindest nicht GNU sed.

7 Stimmen

Im weiteren Sinne, -E ist einzigartig für BSD sed und damit OS X. Links zu man pages. -r bietet erweiterte reguläre Ausdrücke für GNU sed wie in der Korrektur von @stephancheg erwähnt. Seien Sie vorsichtig, wenn Sie einen Befehl verwenden, dessen Variabilität bei verschiedenen 'nix-Distributionen bekannt ist. Ich habe das auf die harte Tour gelernt.

1 Stimmen

Dies ist die richtige Antwort, wenn Sie sed verwenden wollen, und sie ist am ehesten auf die ursprüngliche Frage anwendbar.

2voto

BrianB Punkte 21

Da Sie ausdrücklich angegeben haben, dass Sie sed (anstelle von perl, cut usw.) verwenden wollen, versuchen Sie es mit grouping. Damit umgehen Sie, dass die nicht gierigen Bezeichner möglicherweise nicht erkannt werden. Die erste Gruppe ist das Protokoll (z.B. 'http://', 'https://', 'tcp://', usw.). Die zweite Gruppe ist die Domäne:

echo "http://www.suon.co.uk/product/1/7/3/" | sed "s|^\\(.\*//\\)\\(\[^/\]\*\\).\*$|\\1\\2|"

Wenn Sie mit der Gruppierung nicht vertraut sind, beginnen Sie aquí .

1voto

Iain Henderson Punkte 119

Ich weiß, dass dies ein alter Eintrag ist, aber vielleicht findet ihn jemand nützlich. Da der vollständige Domänenname eine Gesamtlänge von 253 Zeichen nicht überschreiten darf, ersetzen Sie .* durch .\{1, 255\}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X