テキスト ブロック内の URI を特定するにはどうすればよいでしょうか。
アイデアは、そのような一連のテキストをリンクに変えることです。http(s) および ftp(s) スキームのみを考慮した場合、これは非常に簡単に実行できます。ただし、一般的な問題 (tel、mailto、およびその他の URI スキームを考慮した場合) は、はるかに複雑であると推測しています (可能であれば)。
可能であれば、C# でのソリューションを希望します。ありがとうございました。
テキスト ブロック内の URI を特定するにはどうすればよいでしょうか。
アイデアは、そのような一連のテキストをリンクに変えることです。http(s) および ftp(s) スキームのみを考慮した場合、これは非常に簡単に実行できます。ただし、一般的な問題 (tel、mailto、およびその他の URI スキームを考慮した場合) は、はるかに複雑であると推測しています (可能であれば)。
可能であれば、C# でのソリューションを希望します。ありがとうございました。
URI と URL を 1 つのパターンに一致させるのは難しいことで知られていますが、正規表現はこのための良い出発点となる可能性があります。
説明すると、最も単純なパターンはかなり複雑に見えます (Perl 5 表記法で):
\w+:\/{2}[\d\w-]+(\.[\d\w-]+)*(?:(?:\/[^\s/]*))*
これなら合うだろう
http://example.com/foo/bar-baz
と
ftp://192.168.0.1/foo/file.txt
ただし、少なくとも次の場合に問題が発生します。
mailto:support@stackoverflow.com
(一致しない - いいえ//
、しかし存在する@
)ftp://192.168.0.1.2
(一致しますが、数字が多すぎるため、有効な URI ではありません)ftp://1000.120.0.1
(一致しますが、IP アドレスには 0 から 255 までの数字が必要なので、有効な URI ではありません)nonexistantscheme://obvious.false.positive
http://www.google.com/search?q=uri+regular+expression
(一致しますが、クエリはそうではありません。これは80:20ルールのケースだと思います。ほとんどのものをキャッチしたい場合は、自分で書けない場合は、適切な正規表現を見つけることをお勧めします.かなり管理されたソース (機械で生成されたものなど) から取得したテキストを見ている場合は、これが最善の方法です。
遭遇するすべての URI を絶対に積極的にキャッチする必要があり、野生のテキストを見ている場合は、コロンが含まれる単語を探すと思います\s(\w:\S+)\s
。URI の適切な候補を取得したら、使用しているライブラリの URI クラスで実際の URI パーサーに渡します。
なぜ URI パターンを書くのが難しいのかということに興味があるなら、URI の定義はType-2 grammarで行われるのに対し、正規表現はType-3 grammarからの言語しかパースできないからだと思います。
何かが URI であるかどうかは、コンテキストに依存します。一般に、常に共通しているのは、"scheme_name:" で始まることだけです。スキーム名は何でもかまいません (有効な文字に従う)。ただし、他の文字列にも URI ではなくコロンが含まれています。
そのため、関心のあるスキームを決定する必要があります。一般に、関心のある各スキームについて、「scheme_name:」の後にスペースまでの文字を続けて検索することで解決できます。残念ながら、URI にはスペースを含めることができるため、テキストに埋め込まれているとあいまいになる可能性があります。あいまいさを解決するためにあなたにできることは何もありません。テキストを書いた人がそれを修正する必要があります。オプションで、URI を <> で囲むことができます。ただし、ほとんどの人はそうしないので、その形式を認識しても役立つことはまれです。
URI に関するウィキペディアの記事には、関連する RFC がリストされています。
[編集して追加: 正規表現を使用して URI を完全に検証するのは悪夢です。正しいものを見つけたり作成したりしても、非常に大きくなり、コメントや維持が困難になります。幸いなことに、リンクを強調表示するだけの場合は、奇妙な誤検出は気にしないので、検証する必要はありません。「http://」、「mailto:\S*@」などを探してください]
通常のテキストにはそのパターンのインスタンスが多数あるため、「something.tld」にも一致させたい場合は簡単ではありませんが、スキームで始まる URI のみを一致させたい場合は、この正規表現を試すことができます。 (すみません、C# でプラグインする方法がわかりません)
(http|https|ftp|mailto|tel):\S+[/a-zA-Z0-9]
そこにさらにスキームを追加すると、最後の文字が無効ではないことを考慮して、次の空白文字までスキームと一致します (たとえば、非常に一般的な文字列 " http://www.example.com ."のように)。 )
さまざまなニーズに対応する正規表現を使用したコード スニペットを次に示します。
http://snipplr.com/view/6889/regular-expressions-for-uri-validationparsing/
多くのプロトコルでは、引用符なしで「://」を検索するだけで済みます。ただし、他の人についてはわかりません。
URL Tool for Ubiquityは次のことを行います。
findURLs: function(text) {
var urls = [];
var matches = text.match(/(\S+\.{1}[^\s\,\.\!]+)/g);
if (matches) {
for each (var match in matches) {
urls.push(match);
}
}
return urls;
},
次のperlregexpは、トリックを実行する必要があります。c#にはperl正規表現がありますか?
/\w+:\/\/[\w][\w\.\/]*/