2009-03-10 10 views
7

私は、Java Webアプリケーションにwysiwygテキスト領域を持っています。ユーザーはテキストを入力してスタイルを設定したり、HTML形式のテキストを貼り付けることができます。テキストをJavaの正規表現にリンクする

私がしようとしているのはです。のテキストをリンクしています。つまり、テキスト内のすべての可能なURLを「作業相手」に変換します。すなわち、< a href = "..."> ... </a>を追加します。私が持っているすべてはプレーンテキストであるときを働く

このソリューション:

String r = "http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?"; 
Pattern pattern = Pattern.compile(r, Pattern.DOTALL | Pattern.UNIX_LINES | Pattern.CASE_INSENSITIVE); 
Matcher matcher = pattern.matcher(comment); 
comment = matcher.replaceAll("<a href=\"$0\">$0</a>"); // group 0 is the whole expression 

しかし、いくつかすでにフォーマットされたテキストがある場合に問題があるが、「=それはすでにが<のhrefを持っていることすなわち。 .. "> ... </a>タグ。

だから私はそれが2個のHTMLタグ(<>)の間のテキストを見つけるたびと一致しないパターンのためにいくつかの方法を探しています。私はこれがlookaheadまたはlookbehindで達成できると読んだが、私はまだそれを動作させることはできません。私は正規表現がまだ一致するので、間違っていると確信しています。そして、はい、私は周りを遊んでいた/デバッググループ、$ 0に$ 1などを変更します。

アイデア?

+0

タイトルのすべての並べ替えがすでにSO上に存在し、人々が今までにあったソリューションの1つを使い始めるためには、 – Tomalak

+1

私はこの1つで多大な時間を費やして研究しましたが、それでもまだ分かりませんでした。スタックオーバーフローが解決策を見つけるのに役立ち、コミュニティ全体がこれらの答えを利用できるようになりました。 –

+0

私はこの問題の解決方法を1つ表示するように挑戦しています。すでに「並べ替えられたタイトル」となっています。 –

答えて

9

あなたが近くにあります。

hrefの前にあるすべての結果は無視されます。

+0

ありがとう、それは私が必要としていた正確にこれだった...私は本当に非常に近くだった! –

+0

私はいつも "Regular Expression Pocket Reference"を持っています;-) –

0

おそらく、html解析がより適切です(htmlparserなど)。次に、htmlノードを持つことができ、属性内ではなくテキスト内のリンクのみを「リンク」することができます。

0

独自にロールバックする必要がある場合は、少なくともMarkdownのオープンソースの実装で使用されているアルゴリズム/パターンを参照してください(例:)。

1

regexを使いたいのであれば(私はXML/HTMLを最初に解析するのがより堅牢だと思うが)、先読みや意味が意味をなさないと思う。最初の刺しは、あなたの正規表現の末尾にこれを追加することがあります意味

(?!</a>) 

:ただ、その後のタグを閉じてあります場合は一致していません。 (もちろんこれは、永遠に微調整することができます。)これはうまく動作しません、しかし、文字列

<a href="...">http://example.com/</a> 

与えられたこの正規表現は、先読みのために失敗し、「http://example.com/」にマッチしようとしますので、(私たちが期待して)、その後をバックトラック最後に持っている欲張りの修飾子は、 "http://example.com"にマッチします。

+、*、?のいずれかにpossessive qualifierを使用すると、後者の問題を解決できます。演算子 - ちょうどそれらの後にスティック。これにより、バックトラッキングができなくなります。これはおそらくパフォーマンス上の理由からも良いでしょう。

これは(3余分+さんに注意してください)私の作品:

String r = "http(s)?://([\\w+?\\.\\w+])++([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*+)?+(?!</a>)"; 
1

あなたが本当に正規表現でそれをしたい場合は、以下:

String r = "(?<![=\"\\/>])http(s)?://([\\w+?\\.\\w+])+([a-zA-Z0-9\\~\\!\\@\\#\\$\\%\\^\\&amp;\\*\\(\\)_\\-\\=\\+\\\\\\/\\?\\.\\:\\;\\'\\,]*)?"; 

例えばURLが= "または/>に続いていないことを確認してください。