将文本与Java中的正则表达式链接

时间:2009-03-10 11:19:01

标签: java regex

我在Java webapp中有一个所见即所得的文本区域。用户可以输入文本并对其进行样式设置或粘贴一些已经HTML格式的文本。

我要做的是 linkify 文本。这意味着,将文本中的所有可能的URL转换为它们的“工作对应物”,即添加< a href =“...”> ...< / A>

当我所拥有的只是纯文本时,此解决方案可以

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

但问题是当有一些已经格式化的文本时,即它已经具有&lt; a href =“...”&gt; ...&lt; / A&GT;标签

因此,只要找到两个HTML标记(&lt; a&gt;)之间的文本,我就会找到模式不匹配的方法。我已经读过这可以通过lookaheadlookbehind来实现,但我仍然无法使其发挥作用。我确信我做错了因为正则表达式仍然匹配。是的,我一直在玩/调试组,将$ 0改为$ 1等。

有什么想法吗?

5 个答案:

答案 0 :(得分:9)

你很亲密。您可以像这样使用“负面观察”:

(?<!href=")http:// etc

所有以href开头的结果都将被忽略。

答案 1 :(得分:1)

如果你想使用正则表达式,(虽然我认为首先解析为XML / HTML更加健壮)我认为前瞻或后瞻是有道理的。第一次尝试可能是在正则表达式的末尾添加它:

(?!</a>)

含义:如果之后关闭了标签,则不匹配。 (当然,这可以永远调整。)但这并不好用,因为给出了字符串

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

这个正则表达式将尝试匹配“http://example.com/”,由于前瞻(我们希望)失败,然后回溯贪婪的限定符最后匹配“{ {3}}“相反,它没有跟在它之后。

您可以在+,*和?上使用http://example.com解决后一个问题。运营商 - 只需坚持一个+。这可以防止他们进行反向跟踪。出于性能原因,这可能也不错。

这对我有用(注意三个额外的+):

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

答案 2 :(得分:1)

如果你真的想用正则表达式来做,那么:

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

e.g。检查网址是否跟随=“或/&gt;

答案 3 :(得分:0)

也许html解析更适合你(例如htmlparser)。然后你可以拥有html节点,只有文本中的“linkify”链接,而不是属性。

答案 4 :(得分:0)

如果你必须自己动手,至少要看一下Markdown开源实现中使用的算法/模式,例如MarkdownJ