セミランダム文字列から完全なURLを抽出/解析するにはどうすればよいですか?


12

ランダムな短い文字列から完全なURL(およびURLのみ)をbashで解析/抽出したいのですが。

例:

bob, the address is http://www.google.com

または

https://foo.com/category/example.html is up

または

Error 123 occurred at http://bit.ly/~1223456677878

または

Stats are up: https://foo1234.net/report.jpg

使ってみcat foo_output | egrep -o "https?://[\w'-\.]*\s"たがうまくいかなかった。


抽出されたURLで何をしたいかによって、
恐ろしく聞こえ

回答:


24

試しましたか:

egrep -o 'https?://[^ ]+' foo_output

代わりに?

文字クラスを持つものはすべてリテラルとして解釈されるため、言うこと[\w]単語の文字とは一致しないことに注意してください。さらに、文字クラス内で正規表現のメタ文字をエスケープする必要はありません。つまり、言うこと[\.]はとまったく同じではありません[.]


2
[^ ]広すぎる、あなたが他のブランクを除外したいと思う、()、おそらくコマス、およびURLで許可されていないすべての文字。
ステファンChazelas

@StephaneChazelasそうですね。ただし、行の先頭または末尾にない限り、URLの前後にスペースが続くと想定しました。
devnull 2014年

5

URIは、自然言語に埋め込まれた場合の正規表現マッチングには適していません。ただし、現在の最新技術は、John Gruberの改良されたリベラル、一致するURLの正確な正規表現パターンです。現在投稿されているように、1行バージョンは次のとおりです。

(?i)\b((?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))

Johnもここで要点を維持しているようですが、彼のブログエントリは、テストコーパスと正規表現パターンの制限を説明するのにはるかに優れています。

コマンドラインから式を実装する場合、使用している正規表現エンジンまたはシェルの引用の問題によって制限を受けることがあります。Rubyスクリプトが最良の選択肢であることがわかりましたが、実際の距離は異なる場合があります。


2
リンクにリンクする代わりに、正規表現を回答に含めてください。
terdon

@terdon、完全な正規表現は約60行です。
フォンブランド2014年

2
@vonbrand知ってる、見たよ。外部リソースへのリンクを避ける傾向があるだけです。SEサイトの要点はwikiになることです。リンクしたブログがオフラインになった場合はどうなりますか?あなたの答えは役に立たなくなります。とにかく、60行はそれほど多くはなく、読みやすくするために60行にすぎません。
terdon

2

URLの一致に関する問題は、URLにはほとんど何でも入れることができるということです。

https://encrypted.google.com/search?hl=en&q=foo#hl=en&q=foo&tbs=qdr:w,sbd:1

あなたが見ることができるように、上記の(有効な)URLが含まれている$?#&,.:。基本的に、URLに含まれていないことを確認できるのは、空白スペースだけです。これを念頭に置いて、次のような単純なパターンでURLを抽出できます。

$ grep -oP 'http.?://\S+' file 
http://www.google.com
https://foo.com/category/example.html
http://bit.ly/~1223456677878
https://foo1234.net/report.jpg

\S任意の一致する非スペース、Perl互換の正規表現(PCREs)の文字を-PためPCREsをアクティブにgrepし、-oそれはラインのだけマッチしたセグメントを印刷します。


0

私はチェーンに行きますが、少し異なります。あなたのようなテキストスニペットがstrings.txtと呼ばれるテキストファイルにある場合は、次のようにすることができます:

grep http ./strings.txt | sed 's/http/\nhttp/g' | grep ^http | sed 's/\(^http[^ <]*\)\(.*\)/\1/g' | grep IWANTthis | sort -u

説明:

grep http ./st3.txt      => will catch lines with http from text file
sed 's/http/\nhttp/g'    => will insert newline before each http
grep ^http               => will take only lines starting with http
sed 's/\(^http[^ <]*\)\(.*\)/\1/g'   
                         => will preserve string from ^http until first space or < (the latter in hope if 
grep IWANTthis           => will take only urls containing your text of your interest; you can omit this.
sort -u                  => will sort the list and remove duplicates from it 

URLが機能しない可能性があるため、目的のURLで追加のエラーチェックを実行できます。例wget -p URL -O /dev/null-URLが利用できない場合、まったく異なるエラーコードを出力するため、リンクのリストを処理して有効性ステータスを出力するループを設定できます。

最終的にhtmlファイルからリンクを抽出する場合はsed、特別な場合に問題が発生する可能性があります。おかしい(投稿)で提案されているように、おそらくすでに見たことがあるでしょう-正規表現ではなくhtmlパーサーエンジンを使用するのが最善です。そのような簡単に利用できるパーサーの1つは、テキストのみのブラウザーlynx(すべてのLinuxで利用可能)です。これにより、ファイル内のすべてのリンクのリストを即座にダンプし、必要なURLをgrepで抽出できます。

lynx -dump -listonly myhtmlfile.html | grep IWANTthisString | sort -u

ただし、これはほとんどの破損したHTMLファイルまたはリンク付きのテキストスニペットでは機能しません。



-1
cat text-file.txt | grep -Eo '(https?|ftp|file)://[-A-Za-z0-9\+&@#/%?=~_|!:,.;]*[-A-Za-z0-9\+&@#/%=~_|]'

または、SEDコマンドを追加して、CSVファイルに保存します。

| sed 's/;/<tab>/g' > file.csv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.