7
\$\begingroup\$

Your task is to write a program or function that checks if a string is a valid URL.

Given a string as input, you will output a truthy value if the input is a valid URL. If it is not, output a falsey value. An input string is considered a valid URL if all of the following criteria are met:

  • Begins with http:// or https://
  • At least one and up to 128 labels (parts of URL delimited by a period)
    • Labels delimited by a period
    • Contain only letters, digits, and hyphens
    • Do not start nor end with a hyphen
    • Third and fourth characters cannot be a hyphen, unless the first two characters are 'xn'
    • A label may contain zero to 63 characters
  • The length of the string does not exceed 253 characters

This is a code-golf, with standard rules.


https://en.wikipedia.org/wiki/Domain_Name_System#Domain_name_syntax

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG, nice first question. When posting next question use sandbox codegolf.meta.stackexchange.com/questions/2140/… \$\endgroup\$ – Евгений Новиков Jul 29 '17 at 20:30
  • 2
    \$\begingroup\$ A full URL may have many more components than just the scheme and the host: scheme://user:password@host:port/path?query#fragment, to say nothing of schemes other than http/https with their own different URL syntax, or http/https URLs for a literal IPv6 address rather than a hostname. Since you seem to be primarily interested in validating the hostname part, I’d recommend letting the challenge be “check if a string is a valid hostname” and removing the scheme:// entirely. \$\endgroup\$ – Anders Kaseorg Jul 30 '17 at 4:19
  • 2
    \$\begingroup\$ Also, if you read the standard (RFC 952, RFC 1034, RFC 1123, RFC 3696, RFC 5891) rather than Wikipedia: a label cannot be empty; the restriction on the total length is not 253 but rather 255 minus the number of labels; the top-level (last) label may not be all-numeric; and the restriction about the third and fourth characters not being a hyphen refers to the decoded Unicode string represented by an IDN label, not its encoded ASCII representation (and there are many other Unicode-related restrictions that you probably don’t want to think about). \$\endgroup\$ – Anders Kaseorg Jul 30 '17 at 4:42
  • \$\begingroup\$ @AndersKaseorg The question doesn't necessarily have to use real URLs. The question could just as well be called "Check if the string is a valid [some made-up word]" where [some made-up word] is defined with the above criteria. \$\endgroup\$ – ericw31415 Jul 30 '17 at 15:11
  • \$\begingroup\$ Please add some test cases. \$\endgroup\$ – Poke Jul 31 '17 at 2:40
2
\$\begingroup\$

JavaScript, 114 bytes

x=>RegExp(`^(?!.*([./](-|(?!xn)[^/]{2}--)|-[./]|-$))https?://${a='[a-zA-Z0-9-]{0,63}'}(?:\\.${a}){0,127}`).test(x)

Hopes it works.

For real URLs, you should use:

x=>eval(`try{new URL(x)}catch(e){}`)

Thanks to ThePirateBay, construct regex from string save 3 bytes.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.