2009-06-27 15 views
5

Perl正規表現を使用して特定の拡張子(通常は可変サブドメイン)のすべてのURLをプレーンテキストから抽出するにはどうすればよいですか?私が試してみました:regexを使ってPerlでプレーンテキストからURLを抽出する

my $stuff = 'omg http://fail-o-tron.com/bleh omg omg omg omg omg http://homepage.com/woot.gif dfgdfg http://shomepage.com/woot.gif aaa'; 
while($stuff =~ m/(http\:\/\/.*?homepage.com\/.*?\.gif)/gmsi) 
{ 
print $1."\n"; 
} 

をそれは恐ろしく失敗し、私を与える:

http://fail-o-tron.com/bleh omg omg omg omg omg http://homepage.com/woot.gif 
http://shomepage.com/woot.gif 

私は.*?を使用していますので、それはどの非貪欲ことが、私に最小を与えるべき、起こらないだろうと思いました一致。誰かが私が間違っていることを教えてもらえますか? (私はURLを検証するためにいくつかのユーバーコンプレックス、缶詰正規表現を望んでいない。私は私が間違っているのかを知りたいので、私はそれから学ぶことができます)

答えて

5

ログインCPANRegexp::Common::URI

編集:缶詰の正規表現が必要ない場合でも、動作するテスト済みモジュールのソースを調べるのに役立ちます。

特定の文字列に一致するURLを検索する場合は、このモジュールを使用して簡単に検索できます。

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Regexp::Common qw/URI/; 

while (<>) { 
    if (m/$RE{URI}{HTTP}{-keep}/) { 
    print $_ if $1 =~ m/what-you-want/; 
    } 
} 
16

URI::Findは、この問題を解決するために特別に設計されています。すべてのURIを見つけてフィルタリングすることができます。末尾の句読点のようなものに対処するためのヒューリスティックがいくつかあります。

更新:最近、Unicodeを処理するように更新されました。

0

私は使用しているために起こるべきではないと思っていました。それはありませんが、それはあなたのを行く最小の一致を与える非貪欲ことが、私に最小の一致

を与えるべきです。最初のhttpから始まり、右に行くと、それは最も小さいマッチです。

スラッシュをエスケープする必要はありません。セパレータとしてスラッシュを使用する必要がないためです。結腸も逃げる必要はありません。次回は、ちょうどこの操作を行います。

m|(http://.*?homepage.com\/.*?\.gif)| 

または

m#(http://.*?homepage.com\/.*?\.gif)# 

または

m<(http://.*?homepage.com\/.*?\.gif)> 

または他の文字の多くの一つを、はperlreのマニュアルを参照してください。

1

URLにはスペースが含まれていないので、*。 0以上の空白以外の文字には\ S *?を使用してください。

m,(http.*?://([^\s)\"](?!ttp:))+),g 

...:私のために働いているように見えるテキストファイル、|文字列からすべてのURLを取得|抜粋|ここ

+0

[RFC 3986付録C](のhttp:/ /tools.ietf.org/html/rfc3986#appendix-C)では、空白が許されている場合を含め、URIを抽出する際の特別な問題について説明しています。 "いくつかのケースでは、長いURIを改行するために空白(空白、改行、タブなど)を追加する必要があり、URIを抽出するときに空白を無視する必要があります。そして、「堅牢性のために、ユーザー型のURIを受け入れるソフトウェアは区切り文字と埋め込み空白の両方を認識して削除するようにしなければなりません。それは経験から言うと、これは難しいです。 – Schwern

0

は(たぶん)を取得する正規表現ですまたは例では:私のnoobの参考のために

$ echo -e "\n\na blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah \"https://poi.com/a%20b\"; (http://bbb.comhttp://roch.com/abc) \n" | perl -ne 'while (my $string = <>) { print "$string\n"; while ($string =~ m,(http.*?://([^\s)\"](?!ttp:))+),g) {print "$&\n"} }' 


a blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah "https://poi.com/a%20b"; (http://bbb.comhttp://roch.com/abc) 

http://www.abc.com/dss.htm?a=1&p=2#chk 
https://poi.com/a%20b 
http://bbb.com 
http://roch.com/abc 

、ここでは同じコマンドのデバッグバージョンがある上: - 」とし、空白文字を使用して、")

$ echo -e "\n\na blahlah blah:http://www.abc.com/dss.htm?a=1&p=2#chk - blahblah \"https://poi.com/a%20b\"; (http://bbb.comhttp://roch.com/abc) \n" | perl -dne 'use re "debug" ; while (my $string = <>) { print "$string\n"; while ($string =~ m,(http.*?://([^\s)\"](?!ttp:))+),g) {print "$&\n"} }' 

正規表現はhttp(s)://に一致します出口 "文字;次にpositive lookaheadを使用して、最初に "http"リテラルグループの "終了"を引き起こします(すでに一致している場合)。ただし、これも以前の一致の最後の文字を「食べる」ため、先読みの一致は1文字前に「ttp:」に移動されます。

いくつかの有用なページ:

が、これは誰か、
を役に立てば幸い乾杯!

EDIT:ちょうど約URI::Find::Simple - search.cpan.orgたUPSは、同じこと(regex - Getting the website title from a link in a string経由)を行うようだ

2

は、私は*、* .htmのような特定の拡張子
で終わるのリンクを抽出するために、次のコードを使用しています.html、* .gif、* .jpeg。 注:このスクリプト拡張では、* .htmlが最初に書き込まれ、次に* .htmが書き込まれます。どちらも "htm"が共通しているためです。したがって、これらの変更は慎重に行う必要があります。

入力:結果が保存されるリンクと出力ファイル名を持つファイル名。
出力:出力ファイルに保存されます。

コードはここに行く:あなたの文字列の

use strict; 
use warnings; 

if ($#ARGV != 1) { 
print 
"Incorrect number of arguments.\nArguments: Text_LinkFile, Output_File\n"; 
die $!; 
} 
open FILE_LINKS, $ARGV[0] or die $!; 
open FILE_RESULT, ">$ARGV[1]" or die $!; 

my @Links; 
foreach (<FILE_LINKS>) { 
    my @tempArray; 
    my (@Matches) =($_ =~ m/((https?|ftp):\/\/[^\s]+\.(html?|gif|jpe?g))/g); 
    for (my $i = 0 ; $i < $#Matches ; $i += 3) { 
     push(@Links, $Matches[$i]); 
     } 
    } 
print FILE_RESULT join("\n", @Links); 

出力はここにある:

http://homepage.com/woot.gif 
http://shomepage.com/woot.gif 
+0

'(html | htm | gif | jpeg | jpg)'の代わりに '(html?| gif | jpe?g)'を使わないのはなぜですか? –

+0

@BradGilbert:はい、それはいいです:) – Pushpendra

+0

完璧、完璧! –

1
https?\:\/\/[^\s]+[\/\w] 

この正規表現は、私のために働いた

+0

もう少し文脈や説明が良いでしょう。 –

関連する問題