如何使用 Regex 替换 Kotlin 中 Android WebView 中的链接

How to use Regex to replace links in an Android WebView in Kotlin

我在用 Kotlin 编写的 Android 应用程序中使用 WebView 来显示通过 API 响应提供的富文本内容。数据以原始文本的形式给出,混合了一些 HTML 组件 (links),显示在应用程序中。

编写此 Regex 过滤器的目的是捕获未包含在 <a> 标记中的原始 links,并重新格式化它们,以便它们在 Web 视图中以丰富的方式显示。

我目前解决这个问题的尝试包括使用 replace() 和内联函数来捕获 link 并将其替换为 <a> 标签。

我有一个重写函数,它将数据加载到 WebView 并添加一些样式数据以及删除任何 <iframe> 标签。这两个组件有效,但是我使用 pattern 来匹配 URLs 的替换没有任何效果。

给定一个列表:

http://example.com
https://example.com

我期望输出:

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

然而我的模式产生的输入没有变化。

我正在关注此处找到的 URL 匹配模式:https://mathiasbynens.be/demo/url-regex


val pattern = "@(https?|ftp)://(-\.)?([^\s/?\.#-]+\.?)+(/[^\s]*)?$@iS\n".toRegex()
data.replace(pattern) {
    "<a href=\"${it.groupValues[1]}\">auto link</a>"
}

Log.i("TEST", data)

此函数无法在我记录时用正确的 link 替换数据,即使我知道该模式与我输入的 link 相匹配。

我很肯定可能有更好的方法来完成这项任务,但我们似乎也会进行验证,为此我们将从一个简单的表达式开始:

^(https?:\/\/[^\s]+?\.[^\s]+)$

然后我们将在必要时添加更多约束以进行验证,我们将用类似于以下内容的内容替换它:

<a href="">auto link</a>

Demo

下面是完成这项工作的示例代码片段:

var data = "http://example.com <a href=\"http://example.com\">auto link</a>"
val pattern = """(?i)<a\s+[^>]*>[^<]*</a>|(https?|ftp)://(?:-\.)?([^\s/?.#-]+\.?)+(/\S*)?""".toRegex()
    data = data.replace(pattern) {
        if (it.groupValues[1].isNullOrEmpty()) it.value else "<a href=\"${it.value}\">auto link</a>" 
    }
println(data)

输出:

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

Kotlin online demo

请注意,您需要将修改后的值分配回 data 变量。

此外,您使用的是 PHP-like 格式的正则表达式,但在 Kotlin 中,您不应使用正则表达式定界符。相反,您可以使用内联修饰符,例如 (?i) 使模式不区分大小写。

正则表达式详细信息

  • (?i) - 不区分大小写的修饰符
  • <a\s+[^>]*>[^<]*</a> - A 标签模式
  • | - 或
  • (https?|ftp) - 第 1 组,httphttpsftp
  • :// - :// 子串
  • (?:-\.)? - 一个可选的 -. 子串
  • ([^\s/?.#-]+\.?)+ - 除空格外的 1 个或多个字符的一次或多次重复,/?.#- 然后是一个可选的点
  • (/\S*)? - 可选组,/ 后跟 0 个或更多 non-whitespace 个字符。

如果第 1 组匹配,我们将替换为 link。否则,return 返回整个 A 标签。