web-dev-qa-db-ja.com

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

ランダムな短い文字列から完全な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"を使用してみましたが、うまくいきませんでした。

12
Mike B

試しましたか:

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

代わりに?

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

24
devnull

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はGist here を維持しているようにも見えますが、彼のブログエントリは、テストコーパスと正規表現パターンの制限を説明するのにはるかに優れています。

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

5
CodeGnome

URLの一致に関する問題は、anythingが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互換の正規表現(PCRE)の任意の 非スペース 文字に一致し、_-P_は、grepおよび_-o_のPCREをアクティブにします行の一致したセグメントのみを印刷します。

2
terdon

私はチェーンに行きますが、少し異なります。 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で問題が発生する可能性があります。おかしい ((post) ですでに示唆されているように、正規表現ではなくhtmlパーサーエンジンを使用するのが最善の方法です。そのような簡単に利用できるパーサーの1つは、テキストのみのブラウザーlynx(すべてのLinuxで利用可能)です。これにより、ファイル内のすべてのリンクのリストを即座にダンプし、必要なURLをgrepで抽出できます。

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

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

0
r0berts