これは簡単な質問ですが、理解できません。文字列内の URL を検出し、短縮された URL に置き換えたいのです。
私はstackoverflowからこの表現を見つけましたが、結果はただhttp
Pattern p = Pattern.compile("\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]",Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(str);
boolean result = m.find();
while (result) {
for (int i = 1; i <= m.groupCount(); i++) {
String url=m.group(i);
str = str.replace(url, shorten(url));
}
result = m.find();
}
return html;
もっと良いアイデアはないでしょうか?
ベストアンサー1
まず、私は複雑なケースに正規表現を使うことをあまり支持していないということを言っておきます。このようなケースに完璧な表現を書くのは非常に困難です。そうは言っても、私は URL を検出するためのものを 1 つ持っていて、それには 350 行のユニット テスト ケース クラスが付属しており、合格しています。誰かが単純な正規表現から始めて、何年もかけて表現とテスト ケースを拡張し、見つかった問題に対処してきました。それは決して簡単なことではありません。
// Pattern for recognizing a URL, based off RFC 3986
private static final Pattern urlPattern = Pattern.compile(
"(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
+ "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
+ "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
使用例を以下に示します。
Matcher matcher = urlPattern.matcher("foo bar http://example.com baz");
while (matcher.find()) {
int matchStart = matcher.start(1);
int matchEnd = matcher.end();
// now you have the offsets of a URL match
}