1. Overview

In this tutorial, we’ll show how to parse an URL string with URL and URI classes. Additionally, we’ll explain how to extract parameters from the URL using a Regex class.

2. Parsing Using JDK URL Class

Parsing a URL is a typical case in many applications. Because the URL string contains special characters, parsing it is not a trivial task. Here we’ll present how to extract a parameter from a given URL string.

Let’s first use the URL class provided with the JDK. For that purpose, we’ll extend our test class and add an extension function for the URL class:

private fun URL.findParameterValue(parameterName: String): String? {
    return query.split('&').map {
        val parts = it.split('=')
        val name = parts.firstOrNull() ?: ""
        val value = parts.drop(1).firstOrNull() ?: ""
        Pair(name, value)
    }.firstOrNull{it.first == parameterName}?.second
}

The function parses the query object and extracts a value for the given name. To clarify, the function does not do the validation. It is a simple example of how to extract the parameter value. It splits all provided parameters and filters by parameter name.

After that, let’s test it:

@Test
fun `given url when parsed with URL class returns user parameter`() {
    val url = URL(urlToParse)
    val userNameFromUrl = url.findParameterValue("user")
    assertThat(userNameFromUrl).isEqualTo("Bob")
    assertThat(url.protocol).isEqualTo("https")
    assertThat(url.host).isEqualTo("www.baeldung.com")
}

We showed that the findParameterValue function works correctly. Additionally, we tested two other values provided by the URL class.

3. Using URI Class

After that, let’s have a look at the URI class. It provides a similar API as the URL class. Moreover, we can create an extension function similar way as in the previous example:

private fun URI.findParameterValue(parameterName: String): String? {
    return rawQuery.split('&').map {
        val parts = it.split('=')
        val name = parts.firstOrNull() ?: ""
        val value = parts.drop(1).firstOrNull() ?: ""
        Pair(name, value)
    }.firstOrNull { it.first == parameterName }?.second
}

After that, let’s verify it in a test:

@Test
fun `given url when parsed with URI class returns user parameter`() {
    val uri = URI(urlToParse)
    val userNameFromUrl = uri.findParameterValue("user")
    assertThat(userNameFromUrl).isEqualTo("Bob")
    assertThat(uri.scheme).isEqualTo("https")
    assertThat(uri.host).isEqualTo("www.baeldung.com")
}

As in the previous example, the function finds a correct parameter value. Although the URI class is more generic than the URL class, it provides a host and protocol as well.

4. Extracting Parameters Using Regex Class

Now, let’s only extract parameters from the URL using a build-in Regex class:

class ParseUrlTest {

    companion object {
        private const val urlToParse = "https://www.baeldung.com/?reqNo=3&user=Bob&age=12"
        private val REGEX_PATTERN = """https://www.baeldung.com/?.*[?&]user=([^#&]+).*""".toRegex()
    }

    @Test
    fun `given url when parsed should return user parameter`() {
        val userNameFromUrl = REGEX_PATTERN.matchEntire(urlToParse)?.groups?.get(1)?.value
        assertThat(userNameFromUrl).isEqualTo("Bob")
    }
}

First, we created in the companion object the pattern and string to test. We defined the user parameter in the middle of other parameters. Additionally, the regex handles the optional ‘/’ character before the parameters. Then, we used an extension method to create the Regex object. Besides that,  the Regex object may be initialized with the constructor.

After that, we tested our regex. The matchEntire method checks if the entire string matches the pattern. We took the second group from the match, as the group with the zero index corresponds to the whole match.

5. Conclusion

In this short article, we saw how to parse a URL string with URL and URI classes. Moreover, we showed how to extract parameters using the built-in Regex class.

As always, the source code of the examples is available over on GitHub.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.