【问题标题】:Linkify text with regular expressions in Java用Java中的正则表达式链接文本
【发布时间】:2009-03-10 11:19:00
【问题描述】:

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

我要做的是链接文本。这意味着,将文本中所有可能的 URL 转换为它们的“工作对应”,即添加 ...

当我只有纯文本时,此解决方案有效

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

但问题是当有一些已经格式化的文本时,即它已经... 标签。

所以我正在寻找某种方式让模式不匹配,只要它在两个HTML 标记() 之间找到文本。我已经读过这可以通过lookaheadlookbehind 实现,但我仍然无法使其工作。我确定我做错了,因为正则表达式仍然匹配。是的,我一直在玩/调试组,将 $0 更改为 $1 等。

有什么想法吗?

【问题讨论】:

  • 我想知道还有多少关于这个主题的问题,这样标题的每一个排列都已经存在于 SO 上,人们开始使用之前已经制定的解决方案之一。
  • 我花了很多时间在这个上并做了一些研究,但仍然无法弄清楚。堆栈溢出帮助我找到了解决方案,现在整个社区都可以利用这些答案。您的评论不准确且令人反感。
  • 我也挑战你向我展示这个问题的一个解决方案,该解决方案已经在 SO 上使用“置换标题”
  • @frank06:我的评论远非不准确。我在这里花了很多时间,我已经看到这个问题至少十次了。显然,整个社区都没有利用它,因为这似乎是不断被问到的。
  • 自己看看:google.com/…

标签: java regex


【解决方案1】:

你很接近。您可以像这样使用“消极的后视”:

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

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

【讨论】:

  • 谢谢,这正是我需要的……我确实非常接近!
  • 我总是随身携带“正则表达式袖珍参考”;-)
【解决方案2】:

如果你想使用正则表达式,(尽管我认为首先解析为 XML/HTML 更健壮)我认为先行或后行是有意义的。第一次尝试可能是在你的正则表达式末尾添加这个:

(?!</a>)

含义:如果后面有结束标签,则不匹配。 (当然,这可以永远调整。)但这并不好用,因为给定字符串

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

这个正则表达式将尝试匹配“http://example.com/”,由于前瞻(我们希望)而失败,然后回溯最后的贪婪限定符并匹配“http://example.com " 而不是,它后面没有。

您可以通过在 +、* 和 ? 上使用 possessive qualifier 来解决后一个问题。运营商 - 只需在他们后面加上 +。这可以防止他们回溯。出于性能原因,这可能也有好处。

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

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

【讨论】:

    【解决方案3】:

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

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

    例如检查 URL 是否没有跟随 =" 或 />

    【讨论】:

      【解决方案4】:

      也许 html 解析更适合您(例如htmlparser)。然后你可以有 html 节点并且只在文本中而不是在属性中“链接化”链接。

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 2019-04-24
          • 2010-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-09-20
          • 2011-04-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多