API 21(android 5) 及以下的正则表达式模式错误

Regex pattern error on API 21(android 5) and below

Android 5 及以下版本在运行时从我的正则表达式模式中获取错误:

java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 4:
(?<g1>(http|ftp)(s)?://)?(?<g2>[\w-:@])+(?<TLD>\.[\w\-]+)+(:\d+)?((|\?)([\w\-._~:/?#\[\]@!$&'()*+,;=.%])*)*

这是代码示例:

val urlRegex = "(?<g1>(http|ftp)(s)?://)?(?<g2>[\w-:@])+(?<TLD>\.[\w\-]+)+(:\d+)?((|\?)([\w\-._~:/?#\[\]@!$&'()*+,;=.%])*)*"
val sampleUrl = "https://www.google.com"
val urlMatchers = Pattern.compile(urlRegex).matcher(sampleUrl)
assert(urlMatchers.find())

此模式在 21 以上的所有 API 上工作得很好。

早期版本似乎不支持命名组。根据此来源,named groups were introduced in Kotlin 1.2。如果您不需要这些子匹配项并仅使用正则表达式进行验证,请将其删除。

您的正则表达式非常低效,因为它包含许多嵌套的量化组。请参阅下面的 "cleaner" 版本。

此外,您似乎想检查输入字符串中是否存在正则表达式匹配项。使用 Regex#containsMatchIn():

val urlRegex = "(?:(?:http|ftp)s?://)?[\w:@.-]+\.[\w-]+(?::\d+)?\??[\w.~:/?#\[\]@!$&'()*+,;=.%-]*"
val sampleUrl = "https://www.google.com"
val urlMatchers = Regex(urlRegex).containsMatchIn(sampleUrl)
println(urlMatchers) // => true

参见Kotlin demo and the regex demo

如果您需要检查整个字符串匹配使用 matches:

Regex(urlRegex).matches(sampleUrl)

another Kotlin demo

请注意,要定义正则表达式,您需要使用 Regex class 构造函数。