URL parser: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
m (→{{header|Groovy}}: cosmetic changes) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(27 intermediate revisions by 19 users not shown) | |||
Line 57:
:* <nowiki> urn:oasis:names:specification:docbook:dtd:xml:4.1.2 </nowiki>
<br><br>
=={{header|Ada}}==
{{libheader|AWS}}
<syntaxhighlight lang="ada">with Ada.Text_IO;
with AWS.URL;
with AWS.Parameters;
with AWS.Containers.Tables;
procedure URL_Parser is
procedure Parse (URL : in String) is
use AWS.URL, Ada.Text_IO;
use AWS.Containers.Tables;
procedure Put_Cond (Item : in String;
Value : in String;
When_Not : in String := "") is
begin
if Value /= When_Not then
Put (" "); Put (Item); Put_Line (Value);
end if;
end Put_Cond;
Obj : Object;
List : Table_Type;
begin
Put_Line ("Parsing " & URL);
Obj := Parse (URL);
List := Table_Type (AWS.Parameters.List'(AWS.URL.Parameters (Obj)));
Put_Cond ("Scheme: ", Protocol_Name (Obj));
Put_Cond ("Domain: ", Host (Obj));
Put_Cond ("Port: ", Port (Obj), When_Not => "0");
Put_Cond ("Path: ", Path (Obj));
Put_Cond ("File: ", File (Obj));
Put_Cond ("Query: ", Query (Obj));
Put_Cond ("Fragment: ", Fragment (Obj));
Put_Cond ("User: ", User (Obj));
Put_Cond ("Password: ", Password (Obj));
if List.Count /= 0 then
Put_Line (" Parameters:");
end if;
for Index in 1 .. List.Count loop
Put (" "); Put (Get_Name (List, N => Index));
Put (" "); Put ("'" & Get_Value (List, N => Index) & "'");
New_Line;
end loop;
New_Line;
end Parse;
begin
Parse ("foo://example.com:8042/over/there?name=ferret#nose");
Parse ("urn:example:animal:ferret:nose");
Parse ("jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true");
Parse ("ftp://ftp.is.co.za/rfc/rfc1808.txt");
Parse ("http://www.ietf.org/rfc/rfc2396.txt#header1");
Parse ("ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two");
Parse ("mailto:John.Doe@example.com");
Parse ("news:comp.infosystems.www.servers.unix");
Parse ("tel:+1-816-555-1212");
Parse ("telnet://192.0.2.16:80/");
Parse ("urn:oasis:names:specification:docbook:dtd:xml:4.1.2");
Parse ("ssh://alice@example.com");
Parse ("https://bob:pass@example.com/place");
Parse ("http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64");
end URL_Parser;</syntaxhighlight>
{{out}}
<pre>
Parsing foo://example.com:8042/over/there?name=ferret#nose
Scheme: foo
Domain: example.com
Port: 8042
Path: /over/
File: there
Query: name=ferret
Fragment: #nose
Parameters:
name 'ferret'
Parsing urn:example:animal:ferret:nose
Scheme: urn
File: example:animal:ferret:nose
Parsing jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
Scheme: jdbc
Path: mysql://test_user:ouupppssss@localhost:3306/
File: sakila
Query: profileSQL=true
Parameters:
profileSQL 'true'
Parsing ftp://ftp.is.co.za/rfc/rfc1808.txt
Scheme: ftp
Domain: ftp.is.co.za
Port: 21
Path: /rfc/
File: rfc1808.txt
Parsing http://www.ietf.org/rfc/rfc2396.txt#header1
Scheme: http
Domain: www.ietf.org
Port: 80
Path: /rfc/
File: rfc2396.txt
Fragment: #header1
Parsing ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
Scheme: ldap
Domain: 2001:db8::7
Path: /
File: c=GB
Query: objectClass=one&objectClass=two
Parameters:
objectClass 'one'
objectClass 'two'
Parsing mailto:John.Doe@example.com
Scheme: mailto
File: John.Doe@example.com
Parsing news:comp.infosystems.www.servers.unix
Scheme: news
File: comp.infosystems.www.servers.unix
Parsing tel:+1-816-555-1212
Scheme: tel
File: 1-816-555-1212
Parsing telnet://192.0.2.16:80/
Scheme: telnet
Domain: 192.0.2.16
Port: 80
Path: /
Parsing urn:oasis:names:specification:docbook:dtd:xml:4.1.2
Scheme: urn
File: oasis:names:specification:docbook:dtd:xml:4.1.2
Parsing ssh://alice@example.com
Scheme: ssh
Domain: alice@example.com
Path: /
Parsing https://bob:pass@example.com/place
Scheme: https
Domain: example.com
Port: 443
Path: /
File: place
User: bob
Password: pass
Parsing http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
Scheme: http
Domain: example.com
Port: 80
Path: /
Query: a=1&b=2%202&c=3&c=4&d=encoded
Parameters:
a '1'
b '2 2'
c '3'
c '4'
d 'encoded'
</pre>
=={{header|ALGOL 68}}==
Line 62 ⟶ 232:
Uses the URI parser here: [[URL_parser/URI_parser_ALGOL68]].
<
PROC test uri parser = ( STRING uri )VOID:
Line 99 ⟶ 269:
; test uri parser( "https://bob:pass@example.com/place" )
; test uri parser( "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64" )
END</
{{out}}
<pre>
Line 176 ⟶ 346:
</pre>
=={{header|AppleScript}}==
Thanks to AppleScript's ability to interface with some of macOS's ObjectiveC API, the various components can simply be read off from an ''NSURLComponents'' object set from the URL text.
<syntaxhighlight lang="applescript">use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
on parseURLString(URLString)
set output to {URLString}
set indent to tab & "• "
set componentsObject to current application's class "NSURLComponents"'s componentsWithString:(URLString)
repeat with thisKey in {"scheme", "user", "password", "host", "port", "path", "query", "fragment"}
set thisValue to (componentsObject's valueForKey:(thisKey))
if (thisValue is not missing value) then set end of output to indent & thisKey & (" = " & thisValue)
end repeat
return join(output, linefeed)
end parseURLString
on join(listOfText, delimiter)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to delimiter
set output to listOfText as text
set AppleScript's text item delimiters to astid
return output
end join
-- Test code:
local output, URLString
set output to {}
repeat with URLString in {"foo://example.com:8042/over/there?name=ferret#nose", ¬
"urn:example:animal:ferret:nose", ¬
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true", ¬
"ftp://ftp.is.co.za/rfc/rfc1808.txt", ¬
"http://www.ietf.org/rfc/rfc2396.txt#header1", ¬
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two", ¬
"mailto:John.Doe@example.com", ¬
"news:comp.infosystems.www.servers.unix", ¬
"tel:+1-816-555-1212", ¬
"telnet://192.0.2.16:80/", ¬
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2", ¬
"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"}
set end of output to parseURLString(URLString's contents)
end repeat
return join(output, linefeed & linefeed)</syntaxhighlight>
{{output}}
<syntaxhighlight lang="applescript">"foo://example.com:8042/over/there?name=ferret#nose
• scheme = foo
• host = example.com
• port = 8042
• path = /over/there
• query = name=ferret
• fragment = nose
urn:example:animal:ferret:nose
• scheme = urn
• path = example:animal:ferret:nose
jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
• scheme = jdbc
• path = mysql://test_user:ouupppssss@localhost:3306/sakila
• query = profileSQL=true
ftp://ftp.is.co.za/rfc/rfc1808.txt
• scheme = ftp
• host = ftp.is.co.za
• path = /rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt#header1
• scheme = http
• host = www.ietf.org
• path = /rfc/rfc2396.txt
• fragment = header1
ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
• scheme = ldap
• host = [2001:db8::7]
• path = /c=GB
• query = objectClass=one&objectClass=two
mailto:John.Doe@example.com
• scheme = mailto
• path = John.Doe@example.com
news:comp.infosystems.www.servers.unix
• scheme = news
• path = comp.infosystems.www.servers.unix
tel:+1-816-555-1212
• scheme = tel
• path = +1-816-555-1212
telnet://192.0.2.16:80/
• scheme = telnet
• host = 192.0.2.16
• port = 80
• path = /
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
• scheme = urn
• path = oasis:names:specification:docbook:dtd:xml:4.1.2
http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
• scheme = http
• host = example.com
• path = /
• query = a=1&b=2+2&c=3&c=4&d=encoded"</syntaxhighlight>
=={{header|C sharp|C#}}==
<
namespace RosettaUrlParse
Line 213 ⟶ 493:
}
}
</syntaxhighlight>
=={{header|Crystal}}==
This example demonstrates use of the Crystal standard library's <code>URI</code> class.
<syntaxhighlight lang="crystal">require "uri"
examples = ["foo://example.com:8042/over/there?name=ferret#nose",
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
"http://www.ietf.org/rfc/rfc2396.txt#header1",
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
"mailto:John.Doe@example.com",
"news:comp.infosystems.www.servers.unix",
"tel:+1-816-555-1212",
"telnet://192.0.2.16:80/",
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
"https://bob:password@[::1]/place?a=1&b=2%202"]
examples.each do |example|
puts "Parsing \"#{example}\":"
url = URI.parse example
{% for name in ["scheme", "host", "hostname", "port", "path", "userinfo",
"user", "password", "fragment", "query"] %}
unless url.{{name.id}}.nil?
puts " {{name.id}}: \"#{url.{{name.id}}}\""
end
{% end %}
unless url.query_params.empty?
puts " query_params:"
url.query_params.each do |k, v|
puts " #{k}: \"#{v}\""
end
end
puts
end</syntaxhighlight>
{{out}}
<pre>Parsing "foo://example.com:8042/over/there?name=ferret#nose":
scheme: "foo"
host: "example.com"
hostname: "example.com"
port: "8042"
path: "/over/there"
fragment: "nose"
query: "name=ferret"
query_params:
name: "ferret"
Parsing "urn:example:animal:ferret:nose":
scheme: "urn"
path: "example:animal:ferret:nose"
Parsing "jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true":
scheme: "jdbc"
path: "mysql://test_user:ouupppssss@localhost:3306/sakila"
query: "profileSQL=true"
query_params:
profileSQL: "true"
Parsing "ftp://ftp.is.co.za/rfc/rfc1808.txt":
scheme: "ftp"
host: "ftp.is.co.za"
hostname: "ftp.is.co.za"
path: "/rfc/rfc1808.txt"
Parsing "http://www.ietf.org/rfc/rfc2396.txt#header1":
scheme: "http"
host: "www.ietf.org"
hostname: "www.ietf.org"
path: "/rfc/rfc2396.txt"
fragment: "header1"
Parsing "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two":
scheme: "ldap"
host: "[2001:db8::7]"
hostname: "2001:db8::7"
path: "/c=GB"
query: "objectClass=one&objectClass=two"
query_params:
objectClass: "one"
objectClass: "two"
Parsing "mailto:John.Doe@example.com":
scheme: "mailto"
path: "John.Doe@example.com"
Parsing "news:comp.infosystems.www.servers.unix":
scheme: "news"
path: "comp.infosystems.www.servers.unix"
Parsing "tel:+1-816-555-1212":
scheme: "tel"
path: "+1-816-555-1212"
Parsing "telnet://192.0.2.16:80/":
scheme: "telnet"
host: "192.0.2.16"
hostname: "192.0.2.16"
port: "80"
path: "/"
Parsing "urn:oasis:names:specification:docbook:dtd:xml:4.1.2":
scheme: "urn"
path: "oasis:names:specification:docbook:dtd:xml:4.1.2"
Parsing "https://bob:password@[::1]/place?a=1&b=2%202":
scheme: "https"
host: "[::1]"
hostname: "::1"
path: "/place"
userinfo: "bob:password"
user: "bob"
password: "password"
query: "a=1&b=2%202"
query_params:
a: "1"
b: "2 2"</pre>
=={{header|Elixir}}==
<
"foo://example.com:8042/over/there?name=ferret#nose",
"urn:example:animal:ferret:nose",
Line 236 ⟶ 635:
IO.puts "\n#{str}"
IO.inspect URI.parse(str)
end)</
{{out}}
Line 314 ⟶ 713:
<li>The System.URI class does some "Scheme-Based Normalization" (c/f rfc3986 section 6.2.3), i. e. it knows about certain
defaults for some schemes. With the test data this shows with the port numbers for http, ftp, ldap, mailto.</li></ul>
<
open System.Text.RegularExpressions
Line 343 ⟶ 742:
writeline " query:" (if u.Query.Length > 0 then u.Query.Substring(1) else "")
writeline " fragment:" (if u.Fragment.Length > 0 then u.Fragment.Substring(1) else "")
)</
{{out}}
<pre style="height:3cm">
Line 409 ⟶ 808:
This uses Go's standard [https://golang.org/pkg/net/url/ <tt>net/url</tt>] package.
The [https://golang.org/src/net/url/url.go source code] for this package (excluding tests) is in a single file of ~720 lines.
<
import (
Line 483 ⟶ 882:
fmt.Println(" Fragment:", u.Fragment)
}
}</
{{out}}
<pre>
Line 559 ⟶ 958:
Test:
<
[
Line 580 ⟶ 979:
// Results displayed here
println """
|Parsing $url
| scheme = ${u.scheme}
| domain = ${u.host}
| port = ${(u.port + 1) ? u.port : 'default' }
| path = ${u.path ?: u.schemeSpecificPart}
| query = ${u.query}
| fragment = ${u.fragment}""".stripMargin()
}</
Output:
<pre style="height:30ex;overflow:scroll;">
Parsing foo://example.com:8042/over/there?name=ferret#nose
scheme = foo
domain = example.com
port = 8042
path = /over/there
query = name=ferret
fragment = nose
Parsing urn:example:animal:ferret:nose
scheme = urn
domain = null
port = default
path = example:animal:ferret:nose
query = null
fragment = null
Parsing jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
scheme = jdbc
domain = null
port = default
path = mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
query = null
fragment = null
Parsing ftp://ftp.is.co.za/rfc/rfc1808.txt
scheme = ftp
domain = ftp.is.co.za
port = default
path = /rfc/rfc1808.txt
query = null
fragment = null
Parsing http://www.ietf.org/rfc/rfc2396.txt#header1
scheme = http
domain = www.ietf.org
port = default
path = /rfc/rfc2396.txt
query = null
fragment = header1
Parsing ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
scheme = ldap
domain = [2001:db8::7]
port = default
path = /c=GB
query = objectClass=one&objectClass=two
fragment = null
Parsing mailto:John.Doe@example.com
scheme = mailto
domain = null
port = default
path = John.Doe@example.com
query = null
fragment = null
Parsing news:comp.infosystems.www.servers.unix
scheme = news
domain = null
port = default
path = comp.infosystems.www.servers.unix
query = null
fragment = null
Parsing tel:+1-816-555-1212
scheme = tel
domain = null
port = default
path = +1-816-555-1212
query = null
fragment = null
Parsing telnet://192.0.2.16:80/
scheme = telnet
domain = 192.0.2.16
port = 80
path = /
query = null
fragment = null
Parsing urn:oasis:names:specification:docbook:dtd:xml:4.1.2
scheme = urn
domain = null
port = default
path = oasis:names:specification:docbook:dtd:xml:4.1.2
query = null
fragment = null</pre>
Line 683 ⟶ 1,082:
Example uses [https://hackage.haskell.org/package/network-uri <tt>network-uri</tt>] package:
<
import Data.Foldable (for_)
Line 757 ⟶ 1,156:
Nothing -> return ()
Just fragment -> putStrLn $ " fragment = " ++ fragment
putStrLn ""</
{{out}}
<pre>
Line 835 ⟶ 1,234:
Implementation:
<
({. ; ] }.~ 1+[)~ i.&m
)
Line 881 ⟶ 1,280:
export=. ;:'scheme user creds host port path query fragment'
(#~ 0<#@>@{:"1) (,. do each) export
)</
Task examples:
<
┌────────┬─────────────┐
│scheme │foo │
Line 980 ⟶ 1,379:
├──────┼───────────────────────────────────────────────┤
│path │oasis:names:specification:docbook:dtd:xml:4.1.2│
└──────┴───────────────────────────────────────────────┘</
Note that the <code>path</code> of the example <code>jdbc</code> uri is itself a uri which may be parsed:
<
┌──────┬──────────┐
│scheme│mysql │
Line 997 ⟶ 1,396:
├──────┼──────────┤
│path │/sakila │
└──────┴──────────┘</
Also, examples borrowed from the <code>go</code> implementation:
<
┌──────┬───────────┐
│scheme│ssh │
Line 1,032 ⟶ 1,431:
│ ││a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64││
│ │└─────────────────────────────────────────┘│
└──────┴───────────────────────────────────────────┘</
Note that escape decoding is left to the consumer (as well as decoding things like '+' as a replacement for the space character and determining the absolute significance of relative paths and the details of ip address parsing and so on...). This seems like a good match to the hierarchical nature of uri parsing. See [[URL_decoding#J|URL decoding]] for an implementation of escape decoding.
Line 1,041 ⟶ 1,440:
=={{header|Java}}==
Java offers the ''URI'' class which will parse a URL. URNs are not supported.
<syntaxhighlight lang="java">
URI uri;
try {
uri = new
} catch (URISyntaxException exception) {
/* invalid URI */
}
</syntaxhighlight>
You would then use any of the accompanying class methods to retrieve the value you're looking for.<br />
For example, to get the scheme value, you would use the following.
<syntaxhighlight lang="java">
uri.getScheme()
</syntaxhighlight>
It successfully parsed a majority of the test URLs.
<pre>
foo://example.com:8042/over/there?name=ferret#nose
scheme: foo
userinfo:
host: example.com
port: 8042
authority: example.com:8042
path: /over/there
query: name=ferret
fragment: nose
</pre>
To parse the 'jdbc:' URL you'll need to remove the prefix.
<pre>
mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
scheme: mysql
userinfo: test_user:ouupppssss
host: localhost
port: 3306
authority: test_user:ouupppssss@localhost:3306
path: /sakila
query: profileSQL=true
fragment:
</pre>
The others work as expected, except for 'mailto', 'news', and 'tel'.<br />
Although, these are not too complicated to parse. For 'mailto', I used a class with two records.<br />
RFC 6068 defines a 'mailto' scheme. https://datatracker.ietf.org/doc/html/rfc6068.
<syntaxhighlight lang="java">
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class MailTo {
private final To to;
private List<Field> fields;
public MailTo(String string) {
if
throw new NullPointerException();
if (string.isBlank() || !string.toLowerCase().startsWith("mailto:"))
string = string.substring(string.indexOf(':') + 1);
/* we can use the 'URLDecoder' class to decode any entities */
string =
/* the address and fields are separated by a '?' */
int indexOf = string.indexOf('?');
if
address = string.split("@");
else {
address = string.substring(0, indexOf).split("@");
string = string.substring(indexOf + 1);
/* each field is separated by a '&' */
String[] fields = string.split("&");
String[] field;
this.fields = new ArrayList<>(fields.length);
for (String value : fields) {
field = value.split("=");
this.fields.add(new Field(field[0], field[1]));
}
}
to = new To(address[0], address[1]);
}
record To(String user, String host) { }
record Field(String name, String value) { }
}
</syntaxhighlight>
I ran a majority of the examples from RFC 6068 and got the expected results
<pre>
mailto:infobot@example.com?subject=current-issue
user infobot
host example.com
name subject
value current-issue
mailto:list@example.org?In-Reply-To=%3C3469A91.D10AF4C@example.com%3E
user list
host example.org
name In-Reply-To
value <3469A91.D10AF4C@example.com>
</pre>
Both 'tel' and 'news' are similar, and actually simpler.<br />
RFC 3966 outlines the 'tel' syntaxs. https://datatracker.ietf.org/doc/html/rfc3966.<br />
And RFC 5538 outlines the 'news' syntax. https://www.rfc-editor.org/rfc/rfc5538.html.
=={{header|JavaScript}}==
Line 1,091 ⟶ 1,547:
Here is an example, tested against the JavaScript engines of current versions of Chrome and Safari, of taking this 'Gordian knot' approach to the task:
<
var e = document.createElement('a'),
Line 1,136 ⟶ 1,592:
"https://bob:pass@example.com/place",
"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
]);</
Results of applying this approach in the JavaScript of Safari 8
<syntaxhighlight lang="json">[
{
"hash": "#nose",
Line 1,280 ⟶ 1,736:
"search": "?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
}
]</
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq.'''
Since jq does not provide a URL parser, and since the RFC 3986
specification is in fact quite complex, this entry will for the most
part focus on the task of parsing a correctly formed URL into
the five main components specified in Appendix B of the RFC:
# scheme
# authority
# path
# query
# fragment
However, since the Rosetta Code task description above evinces particular interest in
"authority" segments of the form:
* [username:password@]domain[:port]
this entry will adopt a hierarchical approach to parsing so that the
full URL parser defined here will when possible also break down the "authority"
segment into the four components `username`, `password`, `domain` and `port`.
One advantage of this hierarchical approach is that it facilitates
further refinements and extensions, including error-handling
in the event of invalid components.
Note that the regular expression used to define the jq filter `URL` here is
equivalent to the one specified in Appendix B of the RFC and can
therefore be taken as authoritative.
Note also that the following does not tackle the task of decoding special characters (e.g. "+" in the query string).
<syntaxhighlight lang=jq>
# See Appendix B of RFC 3986
def URL:
capture("^((?<scheme>[^:/?#]+):)?(//(?<authority>[^/?#]*))?(?<path>[^?#]*)(\\?(?<query>[^#]*))?(#(?<fragment>.*))?");
# The authority could be of the form: [username:password@]domain[:port]
def authority:
capture( "^((?<username>[^:@/]*):(?<password>[^@]*)@)?(?<domain>[^:?]*)(:(?<port>[0-9]*))?$" );
# The following filter first parses a valid URL into the five basic
# components, producing a JSON object with five keys; if the "authority"
# field can be futher parsed by `authority`, it is replaced by the
# corresponding JSON object.
def uri:
URL
| if .authority
then (.authority|authority) as $authority
| if $authority then .authority |= $authority
else .
end
else .
end;
</syntaxhighlight>
'''Examples'''
<syntaxhighlight lang=jq>
def tests:
"foo://example.com:8042/over/there?name=ferret&color=grey#nose",
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
"http://www.ietf.org/rfc/rfc2396.txt#header1",
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
"mailto:John.Doe@example.com",
"news:comp.infosystems.www.servers.unix",
"tel:+1-816-555-1212",
"telnet://192.0.2.16:80/",
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2"
;
# For brevity, drop the `null`s:
tests
| [., (uri | (.. | select(.==null)) |= empty) ]
</syntaxhighlight>
{{output}}
<pre>
[
"foo://example.com:8042/over/there?name=ferret&color=grey#nose",
{
"scheme": "foo",
"authority": {
"domain": "example.com",
"port": "8042"
},
"path": "/over/there",
"query": "name=ferret&color=grey",
"fragment": "nose"
}
]
[
"urn:example:animal:ferret:nose",
{
"scheme": "urn",
"path": "example:animal:ferret:nose"
}
]
[
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
{
"scheme": "jdbc",
"path": "mysql://test_user:ouupppssss@localhost:3306/sakila",
"query": "profileSQL=true"
}
]
[
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
{
"scheme": "ftp",
"authority": {
"domain": "ftp.is.co.za"
},
"path": "/rfc/rfc1808.txt"
}
]
[
"http://www.ietf.org/rfc/rfc2396.txt#header1",
{
"scheme": "http",
"authority": {
"domain": "www.ietf.org"
},
"path": "/rfc/rfc2396.txt",
"fragment": "header1"
}
]
[
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two"
]
[
"mailto:John.Doe@example.com",
{
"scheme": "mailto",
"path": "John.Doe@example.com"
}
]
[
"news:comp.infosystems.www.servers.unix",
{
"scheme": "news",
"path": "comp.infosystems.www.servers.unix"
}
]
[
"tel:+1-816-555-1212",
{
"scheme": "tel",
"path": "+1-816-555-1212"
}
]
[
"telnet://192.0.2.16:80/",
{
"scheme": "telnet",
"authority": {
"domain": "192.0.2.16",
"port": "80"
},
"path": "/"
}
]
[
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
{
"scheme": "urn",
"path": "oasis:names:specification:docbook:dtd:xml:4.1.2"
}
]
</pre>
=={{header|Julia}}==
This solution uses Julia's [https://github.com/JuliaWeb/URIParser.jl URIParser] package. The <code>detailview</code> function shows all of the non-empty components of the <code>URI</code> object created by this parser. No attempt is made to further parse more complex components, e.g. query or userinfo. Error detection is limited to indicating whether a string is parsable as a URI and providing a hint as to whether the <code>URI</code> is valid (according to this package's <code>isvalid</code> function).
<syntaxhighlight lang="julia">using Printf, URIParser
const FIELDS = names(URI)
Line 1,338 ⟶ 1,967:
println(detailview(uri))
end
</syntaxhighlight>
{{out}}
Line 1,464 ⟶ 2,093:
=={{header|Kotlin}}==
Although the java.net.URL class can parse urls just fine, unfortunately (as far as this task is concerned) the constructor throws an exception if it does not recognize the scheme (or 'protocol' as it calls it). To deal with unrecognized protocols such as 'foo', we therefore need to replace them with a valid protocol such as 'http' to trick the URL class into parsing them properly:
<
import java.net.URL
Line 1,513 ⟶ 2,142:
)
for (url in urls) parseUrl(url)
}</
{{out}}
Line 1,595 ⟶ 2,224:
{{libheader|LuaSocket}}
<
local tests = {
Line 1,622 ⟶ 2,251:
io.write('\n')
end
</syntaxhighlight>
{{out}}
<pre>
Line 1,686 ⟶ 2,315:
path: oasis:names:specification:docbook:dtd:xml:4.1.2
</pre>
=={{header|M2000 Interpreter}}==
===Using M2000 script to parse URL===
<syntaxhighlight lang="m2000 interpreter">
Module checkit {
any=lambda (z$)->{=lambda z$ (a$)->instr(z$,a$)>0}
Line 1,855 ⟶ 2,485:
}
Checkit
</syntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">
Line 1,899 ⟶ 2,529:
===Using an internal function (variation of String$())===
<syntaxhighlight lang="m2000 interpreter">
module Checkit {
Stack New {
Line 1,941 ⟶ 2,571:
}
Checkit
</syntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">
Line 2,102 ⟶ 2,732:
</pre >
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
{{out}}
<pre><|"Scheme" -> "foo", "User" -> None, "Domain" -> "example.com",
Line 2,110 ⟶ 2,740:
=={{header|Nim}}==
The <code>uri</code> module provides a <code>parseUri</code> proc
<syntaxhighlight lang
proc printUri(url: string) =
Line 2,136 ⟶ 2,766:
echo &"\t Opaque: {res.opaque}"
let urls =
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
Line 2,152 ⟶ 2,782:
for url in urls:
printUri(url)</
{{out}}
<pre>foo://example.com:8042/over/there?name=ferret#nose
Line 2,224 ⟶ 2,854:
=={{header|Objeck}}==
<
class Test {
Line 2,249 ⟶ 2,879:
};
}
}</
{{out}}
Line 2,315 ⟶ 2,945:
=={{header|Perl}}==
You can use the URI module from CPAN to parse URIs. Note that the output is a bit different: for example, you don't get the host from the <code>foo://</code> scheme, as host is only valid for schemes that define it.
<
use warnings;
use strict;
Line 2,342 ⟶ 2,972:
}
}</
{{out}}
<pre>foo://example.com:8042/over/there?name=ferret#nose
Line 2,396 ⟶ 3,026:
scheme urn
path oasis:names:specification:docbook:dtd:xml:4.1.2</pre>
=={{header|Phix}}==
There
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">url</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_url_details</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">uri</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">uri</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">parse_url</span><span style="color: #0000FF;">(</span><span style="color: #000000;">uri</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">url_element_desc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s : %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span>
<span style="color: #008000;">"foo://example.com:8042/over/there?name=ferret#nose"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"urn:example:animal:ferret:nose"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"ftp://ftp.is.co.za/rfc/rfc1808.txt"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"http://www.ietf.org/rfc/rfc2396.txt#header1"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"mailto:John.Doe@example.com"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"news:comp.infosystems.www.servers.unix"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"tel:+1-816-555-1212"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"telnet://192.0.2.16:80/"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"urn:oasis:names:specification:docbook:dtd:xml:4.1.2"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"ssh://alice@example.com"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"https://bob:pass@example.com/place"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"</span>
<span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">show_url_details</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{Out}}
<pre>
Line 2,610 ⟶ 3,142:
query : "a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
</pre>
=={{header|PHP}}==
Using the parse_url function (Parse a URL and return its components)
<syntaxhighlight lang="php"><?php
$urls = array(
'foo://example.com:8042/over/there?name=ferret#nose',
'urn:example:animal:ferret:nose',
'jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true',
'ftp://ftp.is.co.za/rfc/rfc1808.txt',
'http://www.ietf.org/rfc/rfc2396.txt#header1',
'ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two',
'mailto:John.Doe@example.com',
'news:comp.infosystems.www.servers.unix',
'tel:+1-816-555-1212',
'telnet://192.0.2.16:80/',
'urn:oasis:names:specification:docbook:dtd:xml:4.1.2',
);
foreach ($urls AS $url) {
$p = parse_url($url);
echo $url, PHP_EOL;
print_r($p);
echo PHP_EOL;
}</syntaxhighlight>
{{out}}
<pre style="height:256px">foo://example.com:8042/over/there?name=ferret#nose
Array
(
[scheme] => foo
[host] => example.com
[port] => 8042
[path] => /over/there
[query] => name=ferret
[fragment] => nose
)
urn:example:animal:ferret:nose
Array
(
[scheme] => urn
[path] => example:animal:ferret:nose
)
jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
Array
(
[scheme] => jdbc
[path] => mysql://test_user:ouupppssss@localhost:3306/sakila
[query] => profileSQL=true
)
ftp://ftp.is.co.za/rfc/rfc1808.txt
Array
(
[scheme] => ftp
[host] => ftp.is.co.za
[path] => /rfc/rfc1808.txt
)
http://www.ietf.org/rfc/rfc2396.txt#header1
Array
(
[scheme] => http
[host] => www.ietf.org
[path] => /rfc/rfc2396.txt
[fragment] => header1
)
ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
Array
(
[scheme] => ldap
[host] => [2001:db8::7]
[path] => /c=GB
[query] => objectClass=one&objectClass=two
)
mailto:John.Doe@example.com
Array
(
[scheme] => mailto
[path] => John.Doe@example.com
)
news:comp.infosystems.www.servers.unix
Array
(
[scheme] => news
[path] => comp.infosystems.www.servers.unix
)
tel:+1-816-555-1212
Array
(
[scheme] => tel
[path] => +1-816-555-1212
)
telnet://192.0.2.16:80/
Array
(
[scheme] => telnet
[host] => 192.0.2.16
[port] => 80
[path] => /
)
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
Array
(
[scheme] => urn
[path] => oasis:names:specification:docbook:dtd:xml:4.1.2
)</pre>
=={{header|PowerShell}}==
I was confused about the '''Path''' parameter. PowerShell returns '''LocalPath''', '''AbsolutePath''' and '''AbsoluteUri'''; I defaulted to '''LocalPath''', but all properties are returned in the <code>$parsedUrls</code> variable.
<syntaxhighlight lang="powershell">
function Get-ParsedUrl
{
Line 2,657 ⟶ 3,306:
}
}
</syntaxhighlight>
<syntaxhighlight lang="powershell">
[string[]]$urls = @'
foo://example.com:8042/over/there?name=ferret#nose
Line 2,676 ⟶ 3,325:
$parsedUrls | Select-Object -Property Scheme, Port, Domain, Path, Query, Fragment | Format-Table
</syntaxhighlight>
{{Out}}
<pre>
Line 2,696 ⟶ 3,345:
=={{header|Python}}==
Links to Python Documentation: v2: [https://docs.python.org/2/library/urlparse.html#module-urlparse], v3: [https://docs.python.org/3.4/library/urllib.parse.html]
<
url = up.urlparse('http://user:pass@example.com:8081/path/file.html;params?query1=1#fragment')
Line 2,710 ⟶ 3,359:
print('url.username = ', url.username)
print('url.password = ', url.password)
</syntaxhighlight>
{{out}}
<pre>
Line 2,723 ⟶ 3,372:
url.username = user
url.password = pass
</pre>
=={{header|R}}==
urltools::url_parse() do all the actually work. The rest is just for nice output.
<syntaxhighlight lang="rsplus">
library(urltools)
urls <- c("foo://example.com:8042/over/there?name=ferret#nose",
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
"http://www.ietf.org/rfc/rfc2396.txt#header1",
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
"mailto:John.Doe@example.com",
"news:comp.infosystems.www.servers.unix",
"tel:+1-816-555-1212",
"telnet://192.0.2.16:80/",
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
"ssh://alice@example.com",
"https://bob:pass@example.com/place",
"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64")
for (an_url in urls) {
parsed <- url_parse(an_url)
cat(an_url,"\n")
for (idx in 1:ncol(parsed)) {
if (!is.na(parsed[[idx]])) {
cat(colnames(parsed)[[idx]],"\t:",parsed[[idx]],"\n")
}
}
cat("\n")
}
</syntaxhighlight>
{{out}}
<pre>
foo://example.com:8042/over/there?name=ferret#nose
scheme : foo
domain : example.com
port : 8042
path : over/there
parameter : name=ferret
fragment : nose
urn:example:animal:ferret:nose
domain : urn
port : example:animal:ferret:nose
jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
scheme : jdbc:mysql
domain : localhost
port : 3306
path : sakila
parameter : profileSQL=true
ftp://ftp.is.co.za/rfc/rfc1808.txt
scheme : ftp
domain : ftp.is.co.za
path : rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt#header1
scheme : http
domain : www.ietf.org
path : rfc/rfc2396.txt
fragment : header1
ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
scheme : ldap
path : c=GB
parameter : objectClass=one&objectClass=two
mailto:John.Doe@example.com
domain : example.com
news:comp.infosystems.www.servers.unix
domain : news
port : comp.infosystems.www.servers.unix
tel:+1-816-555-1212
domain : tel
port : +1-816-555-1212
telnet://192.0.2.16:80/
scheme : telnet
domain : 192.0.2.16
port : 80
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
domain : urn
port : oasis:names:specification:docbook:dtd:xml:4.1.2
ssh://alice@example.com
scheme : ssh
domain : example.com
https://bob:pass@example.com/place
scheme : https
domain : example.com
path : place
http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
scheme : http
domain : example.com
parameter : a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
</pre>
Line 2,728 ⟶ 3,480:
Links: [http://docs.racket-lang.org/net/url.html?q=url#%28def._%28%28lib._net%2Furl-structs..rkt%29._url%29%29 <code>url</code> structure in Racket documentation].
<
(require racket/match net/url)
(define (debug-url-string U)
Line 2,763 ⟶ 3,515:
"tel:+1-816-555-1212"
"telnet://192.0.2.16:80/"
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2"))</
{{out}}
Line 2,844 ⟶ 3,596:
path bits: ("oasis:names:specification:docbook:dtd:xml:4.1.2")</pre>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-11-02}}
Uses the URI library which implements a Raku grammar based on the RFC 3986 BNF grammar.
<syntaxhighlight lang="raku" line>use URI;
use URI::Escape;
my @test-uris = <
foo://example.com:8042/over/there?name=ferret#nose
urn:example:animal:ferret:nose
jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt#header1
ldap://[2001:db8::7]/c=GB?objectClass?one
mailto:John.Doe@example.com
news:comp.infosystems.www.servers.unix
tel:+1-816-555-1212
telnet://192.0.2.16:80/
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
ssh://alice@example.com
https://bob:pass@example.com/place
http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
>;
my $u = URI.new;
for @test-uris -> $uri {
say "URI:\t", $uri;
$u.parse($uri);
for <scheme host port path query frag> -> $t {
my $token = try {$u."$t"()} || '';
say "$t:\t", uri-unescape $token.Str if $token;
}
say '';
}</syntaxhighlight>
{{out}}
<pre>URI: foo://example.com:8042/over/there?name=ferret#nose
scheme: foo
host: example.com
port: 8042
path: /over/there
query: name=ferret
frag: nose
URI: urn:example:animal:ferret:nose
scheme: urn
path: example:animal:ferret:nose
URI: jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
scheme: jdbc
path: mysql://test_user:ouupppssss@localhost:3306/sakila
query: profileSQL=true
URI: ftp://ftp.is.co.za/rfc/rfc1808.txt
scheme: ftp
host: ftp.is.co.za
port: 21
path: /rfc/rfc1808.txt
URI: http://www.ietf.org/rfc/rfc2396.txt#header1
scheme: http
host: www.ietf.org
port: 80
path: /rfc/rfc2396.txt
frag: header1
URI: ldap://[2001:db8::7]/c=GB?objectClass?one
scheme: ldap
host: [2001:db8::7]
port: 389
path: /c=GB
query: objectClass?one
URI: mailto:John.Doe@example.com
scheme: mailto
path: John.Doe@example.com
URI: news:comp.infosystems.www.servers.unix
scheme: news
port: 119
path: comp.infosystems.www.servers.unix
URI: tel:+1-816-555-1212
scheme: tel
path: 1-816-555-1212
URI: telnet://192.0.2.16:80/
scheme: telnet
host: 192.0.2.16
port: 80
path: /
URI: urn:oasis:names:specification:docbook:dtd:xml:4.1.2
scheme: urn
path: oasis:names:specification:docbook:dtd:xml:4.1.2
URI: ssh://alice@example.com
scheme: ssh
host: example.com
port: 22
path:
URI: https://bob:pass@example.com/place
scheme: https
host: example.com
port: 443
path: /place
URI: http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
scheme: http
host: example.com
port: 80
path: /
query: a=1&b=2 2&c=3&c=4&d=encoded</pre>
=={{header|Ruby}}==
Line 2,849 ⟶ 3,715:
As you can see in the output below, the URI library doesn't parse all of these as recommended.
<
test_cases = [
Line 2,876 ⟶ 3,742:
puts " #{attr.rjust(8)} = #{uri.send(attr)}" if uri.send(attr)
end
end</
{{out}}
<pre>foo://example.com:8042/over/there?name=ferret#nose
Line 2,937 ⟶ 3,803:
path = /
query = a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">use url::Url;
fn print_fields(url: Url) -> () {
println!("scheme: {}", url.scheme());
println!("username: {}", url.username());
if let Some(password) = url.password() {
println!("password: {}", password);
}
if let Some(domain) = url.domain() {
println!("domain: {}", domain);
}
if let Some(port) = url.port() {
println!("port: {}", port);
}
println!("path: {}", url.path());
if let Some(query) = url.query() {
println!("query: {}", query);
}
if let Some(fragment) = url.fragment() {
println!("fragment: {}", fragment);
}
}
fn main() {
let urls = vec![
"foo://example.com:8042/over/there?name=ferret#nose",
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
"http://www.ietf.org/rfc/rfc2396.txt#header1",
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
"mailto:John.Doe@example.com",
"news:comp.infosystems.www.servers.unix",
"tel:+1-816-555-1212",
"telnet://192.0.2.16:80/",
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
"ssh://alice@example.com",
"https://bob:pass@example.com/place",
"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64",
];
for url in urls {
println!("Parsing {}", url);
match Url::parse(url) {
Ok(valid_url) => {
print_fields(valid_url);
println!();
}
Err(e) => println!("Error Parsing url - {:?}", e),
}
}
}
</syntaxhighlight>
Output:
<pre>
Parsing foo://example.com:8042/over/there?name=ferret#nose
scheme: foo
username:
domain: example.com
port: 8042
path: /over/there
query: name=ferret
fragment: nose
Parsing urn:example:animal:ferret:nose
scheme: urn
username:
path: example:animal:ferret:nose
Parsing jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
scheme: jdbc
username:
path: mysql://test_user:ouupppssss@localhost:3306/sakila
query: profileSQL=true
Parsing ftp://ftp.is.co.za/rfc/rfc1808.txt
scheme: ftp
username:
domain: ftp.is.co.za
path: /rfc/rfc1808.txt
Parsing http://www.ietf.org/rfc/rfc2396.txt#header1
scheme: http
username:
domain: www.ietf.org
path: /rfc/rfc2396.txt
fragment: header1
Parsing ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
scheme: ldap
username:
path: /c=GB
query: objectClass=one&objectClass=two
Parsing mailto:John.Doe@example.com
scheme: mailto
username:
path: John.Doe@example.com
Parsing news:comp.infosystems.www.servers.unix
scheme: news
username:
path: comp.infosystems.www.servers.unix
Parsing tel:+1-816-555-1212
scheme: tel
username:
path: +1-816-555-1212
Parsing telnet://192.0.2.16:80/
scheme: telnet
username:
domain: 192.0.2.16
port: 80
path: /
Parsing urn:oasis:names:specification:docbook:dtd:xml:4.1.2
scheme: urn
username:
path: oasis:names:specification:docbook:dtd:xml:4.1.2
Parsing ssh://alice@example.com
scheme: ssh
username: alice
domain: example.com
path:
Parsing https://bob:pass@example.com/place
scheme: https
username: bob
password: pass
domain: example.com
path: /place
Parsing http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
scheme: http
username:
domain: example.com
path: /
query: a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
</pre>
=={{header|Scala}}==
<
object WebAddressParser extends App {
Line 2,972 ⟶ 3,985:
} catch { case ex: Throwable => println('\u2718') }
}
}</
{{Out}}See it in running in your browser by [https://scastie.scala-lang.org/GZdtfkhfRsa9QPKZQ7W4XQ Scastie (JVM)].
=={{header|Tcl}}==
Line 2,986 ⟶ 4,000:
The <tt>uri</tt> package doesn't presently handle IPv6 syntx as used in the example: a bug and patch will be submitted presently ..
<
package require uri::urn
Line 3,025 ⟶ 4,039:
puts \n$uri
pdict [parse_uri $uri]
}</
{{out}}
Line 3,086 ⟶ 4,100:
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
Function parse_url(url)
parse_url = "URL: " & url
Line 3,183 ⟶ 4,197:
WScript.StdOut.WriteLine "-------------------------------"
WScript.StdOut.WriteLine parse_url("this code is messy, long, and needs a makeover!!!")
</syntaxhighlight>
{{Out}}
Line 3,245 ⟶ 4,259:
URL: this code is messy, long, and needs a makeover!!!
Invalid!!!
</pre>
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import net.urllib
const urls = ['jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true',
'ftp://ftp.is.co.za/rfc/rfc1808.txt',
'http://www.ietf.org/rfc/rfc2396.txt#header1',
'ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two',
'mailto:John.Doe@example.com',
'news:comp.infosystems.www.servers.unix',
'tel:+1-816-555-1212',
'telnet://192.0.2.16:80/',
'urn:oasis:names:specification:docbook:dtd:xml:4.1.2',
'foo://example.com:8042/over/there?name=ferret#nose'
]
fn main() {
for url in urls {
u := urllib.parse(url)?
println(u)
print_url(u)
}
}
fn print_url(u urllib.URL) {
println(" Scheme: $u.scheme")
if u.opaque != "" {
println(" Opaque: $u.opaque")
}
if u.str() == '' {
println(" Username: $u.user.username")
if u.user.password != '' {
println(" Password: $u.user.password")
}
}
if u.host != "" {
if u.port() != '' {
println(" Host: ${u.hostname()}")
println(" Port: ${u.port()}")
} else {
println(" Host: $u.host")
}
}
if u.path != "" {
println(" Path: $u.path")
}
if u.raw_query != "" {
println(" RawQuery: $u.raw_query")
m := u.query().data
for q in m {
println(" Key: $q.key Values: $q.value")
}
}
if u.fragment != "" {
println(" Fragment: $u.fragment")
}
}</syntaxhighlight>
{{out}}
<pre>jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
Scheme: jdbc
Opaque: mysql://test_user:ouupppssss@localhost:3306/sakila
RawQuery: profileSQL=true
Key: profileSQL Values: true
ftp://ftp.is.co.za/rfc/rfc1808.txt
Scheme: ftp
Host: ftp.is.co.za
Path: /rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt#header1
Scheme: http
Host: www.ietf.org
Path: /rfc/rfc2396.txt
Fragment: header1
ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
Scheme: ldap
Host: [2001:db8::7]
Path: /c=GB
RawQuery: objectClass=one&objectClass=two
Key: objectClass Values: one
Key: objectClass Values: two
mailto:John.Doe@example.com
Scheme: mailto
Opaque: John.Doe@example.com
news:comp.infosystems.www.servers.unix
Scheme: news
Opaque: comp.infosystems.www.servers.unix
tel:+1-816-555-1212
Scheme: tel
Opaque: +1-816-555-1212
telnet://192.0.2.16:80/
Scheme: telnet
Host: 192.0.2.16
Port: 80
Path: /
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
Scheme: urn
Opaque: oasis:names:specification:docbook:dtd:xml:4.1.2
foo://example.com:8042/over/there?name=ferret#nose
Scheme: foo
Host: example.com
Port: 8042
Path: /over/there
RawQuery: name=ferret
Key: name Values: ferret
Fragment: nose
</pre>
=={{header|Wren}}==
{{trans|VBScript}}
... though modified quite a bit.
<syntaxhighlight lang="wren">var urlParse = Fn.new { |url|
var parseUrl = "URL = " + url
var index
if ((index = url.indexOf("//")) && index >= 0 && url[0...index].count { |c| c == ":" } == 1) {
// parse the scheme
var scheme = url.split("//")
parseUrl = parseUrl + "\n" + "Scheme = " + scheme[0][0..-2]
// parse the domain
var domain = scheme[1].split("/")
// check if the domain includes a username, password and port
if (domain[0].contains("@")) {
var cred = domain[0].split("@")
var split = [cred[0], ""]
if (cred[0].contains(".")) {
split = cred[0].split(".")
} else if (cred[0].contains(":")) {
split = cred[0].split(":")
}
var username = split[0]
var password = split[1]
parseUrl = parseUrl + "\n" + "Username = " + username
if (password != "") parseUrl = parseUrl + "\n" + "Password = " + password
// check if the domain has a port
if (cred[1].contains(":")) {
split = cred[1].split(":")
var host = split[0]
var port = ":" + split[1]
parseUrl = parseUrl + "\n" + "Domain = " + host + "\n" + "Port = " + port
} else {
parseUrl = parseUrl + "\n" + "Domain = " + cred[1]
}
} else if (domain[0].contains(":") && !domain[0].contains("[") && !domain[0].contains("]")) {
var split = domain[0].split(":")
var host = split[0]
var port = ":" + split[1]
parseUrl = parseUrl + "\n" + "Domain = " + host + "\n" + "Port = " + port
} else if (domain[0].contains("[") && domain[0].contains("]:")) {
var split = domain[0].split("]")
var host = split[0] + "]"
var port = ":" + split[1][1..-1]
parseUrl = parseUrl + "\n" + "Domain = " + host + "\n" + "Port = " + port
} else {
parseUrl = parseUrl + "\n" + "Domain = " + domain[0]
}
// parse the path if it exists
if (domain.count > 1) {
var path = "/"
for (i in 1...domain.count) {
if (i < domain.count - 1) {
path = path + domain[i] + "/"
} else if (domain[i].contains("?")) {
var split = domain[i].split("?")
path = path + split[0]
if (domain[i].contains("#")) {
var split2 = split[1].split("#")
var query = split2[0]
var fragment = split2[1]
path = path + "\n" + "Query = " + query + "\n" + "Fragment = " + fragment
} else {
var query = split[1]
path = path + "\n" + "Query = " + query
}
} else if (domain[i].contains("#")) {
var split = domain[i].split("#")
var fragment = split[1]
path = path + split[0] + "\n" + "Fragment = " + fragment
} else {
path = path + domain[i]
}
}
parseUrl = parseUrl + "\n" + "Path = " + path
}
} else if (url.contains(":")) {
var index = url.indexOf(":")
var scheme = url[0...index]
parseUrl = parseUrl + "\n" + "Scheme = " + scheme + "\n"
var path = url[index+1..-1]
if (!path.contains("?")) {
parseUrl = parseUrl + "Path = " + path
} else {
var split = path.split("?")
var query = split[1]
parseUrl = parseUrl + "Path = " + split[0] + "\n"
if (!query.contains("#")) {
parseUrl = parseUrl + "Query = " + query
} else {
split = query.split("#")
var fragment = split[1]
parseUrl = parseUrl + "Query = " + split[0] + "Fragment = " + fragment
}
}
} else {
parseUrl = parseUrl + "\n" + "Invalid!!!"
}
System.print(parseUrl)
System.print()
}
var urls = [
"foo://example.com:8042/over/there?name=ferret#nose",
"urn:example:animal:ferret:nose",
"jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true",
"ftp://ftp.is.co.za/rfc/rfc1808.txt",
"http://www.ietf.org/rfc/rfc2396.txt#header1",
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
"mailto:John.Doe@example.com",
"news:comp.infosystems.www.servers.unix",
"tel:+1-816-555-1212",
"telnet://192.0.2.16:80/",
"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
"ssh://alice@example.com",
"https://bob:pass@example.com/place",
"http://example.com/?a=1&b=2+2&c=3&c=4&d=\%65\%6e\%63\%6F\%64\%65\%64"
]
for (url in urls) urlParse.call(url)</syntaxhighlight>
{{out}}
<pre>
URL = foo://example.com:8042/over/there?name=ferret#nose
Scheme = foo
Domain = example.com
Port = :8042
Path = /over/there
Query = name=ferret
Fragment = nose
URL = urn:example:animal:ferret:nose
Scheme = urn
Path = example:animal:ferret:nose
URL = jdbc:mysql://test_user:ouupppssss@localhost:3306/sakila?profileSQL=true
Scheme = jdbc
Path = mysql://test_user:ouupppssss@localhost:3306/sakila
Query = profileSQL=true
URL = ftp://ftp.is.co.za/rfc/rfc1808.txt
Scheme = ftp
Domain = ftp.is.co.za
Path = /rfc/rfc1808.txt
URL = http://www.ietf.org/rfc/rfc2396.txt#header1
Scheme = http
Domain = www.ietf.org
Path = /rfc/rfc2396.txt
Fragment = header1
URL = ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two
Scheme = ldap
Domain = [2001:db8::7]
Path = /c=GB
Query = objectClass=one&objectClass=two
URL = mailto:John.Doe@example.com
Scheme = mailto
Path = John.Doe@example.com
URL = news:comp.infosystems.www.servers.unix
Scheme = news
Path = comp.infosystems.www.servers.unix
URL = tel:+1-816-555-1212
Scheme = tel
Path = +1-816-555-1212
URL = telnet://192.0.2.16:80/
Scheme = telnet
Domain = 192.0.2.16
Port = :80
Path = /
URL = urn:oasis:names:specification:docbook:dtd:xml:4.1.2
Scheme = urn
Path = oasis:names:specification:docbook:dtd:xml:4.1.2
URL = ssh://alice@example.com
Scheme = ssh
Username = alice
Domain = example.com
URL = https://bob:pass@example.com/place
Scheme = https
Username = bob
Password = pass
Domain = example.com
Path = /place
URL = http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
Scheme = http
Domain = example.com
Path = /
Query = a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
</pre>
|