URL parser: Difference between revisions

→‎{{header|AppleScript}}: Rewritten to read the NSURLComponents object's properties directly and format with AppleScript. Waffle reduced.
(Added AppleScript.)
(→‎{{header|AppleScript}}: Rewritten to read the NSURLComponents object's properties directly and format with AppleScript. Waffle reduced.)
Line 179:
=={{header|AppleScript}}==
 
Thanks to AppleScript's ability to interface with some of macOS's ObjectiveC API, AppleScript text representing a URL can be used to get an ''NSURLComponents'' object, from which the various components can simply be read off infrom various forms. But for the purpose of presenting the components as nicely laid-out text, it's simplest to edit thean ''NSURLComponents'' object's 'description'set from the string:URL text.
 
<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
Line 185:
 
on parseURLString(URLString)
set end of output to parseURLString({URLString)}
-- Derive an NSURLComponents object from the input string.
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"}
-- Get the object's 'description' text to edit into the required form.
set outputStringthisValue to (componentsObject's |description|valueForKey:(thisKey)'s mutableCopy()
if (thisValue is not missing value) then set end of output to indent & thisKey & (" = " & thisValue)
set useRegex to current application's NSRegularExpressionSearch
end repeat
-- Zap everything outside the component list and any entries with '(null)' values.
tell outputString to replaceOccurrencesOfString:("^[^{]++\\{|(?:, )?[a-z]++ = \\(null\\)|\\}$") withString:("") options:(useRegex) range:({0, its |length|()})
-- Replace comma-space separators between entries with linefeeds.
tell outputString to replaceOccurrencesOfString:(", ") withString:(linefeed) options:(0) range:({0, its |length|()})
-- Indent and bullet each entry.
tell outputString to replaceOccurrencesOfString:("(?m)^") withString:(tab & "•" & space) options:(useRegex) range:({0, its |length|()})
return join(output, linefeed)
-- Append the result to the original URL string and return.
return (URLString as text) & linefeed & outputString
end parseURLString
 
on join(listOfText, delimiter)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to astiddelimiter
set output to outputlistOfText as text
set AppleScript's text item delimiters to linefeed & linefeedastid
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", ¬
Line 208 ⟶ 212:
"ftp://ftp.is.co.za/rfc/rfc1808.txt", ¬
"http://www.ietf.org/rfc/rfc2396.txt#header1", ¬
"https://John.Smith:1234@www.mybank.com/blah/blah/blah?idiot=too%20true", ¬
"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two", ¬
"mailto:John.Doe@example.com", ¬
Line 214 ⟶ 217:
"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)
set end of output to parseURLString(URLString's contents)
end repeat
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to linefeed & linefeed
set output to output as text
set AppleScript's text item delimiters to astid
 
return join(output, linefeed & linefeed)</lang>
 
{{output}}
<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
 
https://John.Smith:1234@www.mybank.com/blah/blah/blah?idiot=too%20true
• scheme = https
• user = John.Smith
• password = 1234
• host = www.mybank.com
• path = /blah/blah/blah
• query = idiot=too%20true
 
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"</lang>
 
More usefully in a script, the individual properties can be read off directly. For example:
 
<lang applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"
 
set URLString to "https://John.Smith:1234@www.mybank.com/blah/blah/blah?idiot=too%20true"
set componentsObject to current application's class "NSURLComponents"'s componentsWithString:(URLString)
 
set encodedQuery to (componentsObject's percentEncodedQuery()) as text
-- or: set encodedQuery to (componentsObject's valueForKey:("percentEncodedQuery")) as text
--> "idiot=too%20true"
set decodedQuery to (componentsObject's query()) as text -- Simile.
--> "idiot=too true"
set queryRangeInURL to componentsObject's rangeOfQuery() -- Ditto.
--> {location:54, |length|:16} -- 'location' is 0-based.
 
http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64
-- Etc.</lang>
• scheme = httpshttp
• host = www.mybankexample.com
• path = /
• query = a=1&b=2+2&c=3&c=4&d=encoded"</lang>
 
=={{header|Arturo}}==
557

edits