Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Create the shortest regular expression that will roughly match a URL in text when run in JavaScript

Example:

"some text exampley.com".match(/your regular expression goes here/);

The regular expression needs to

  • capture all valid URLS that are for http and https.
  • not worry about not matching for URL looking strings that aren't actually valid URLS like 'super.awesome/cool'
  • be valid when run as a JavaScript regex

Test criteria:

Match:

Not Match:

  • example
  • super/cool
  • Good Morning
  • i:can
  • hello.

Here is a test that might help clarify a bit http://jsfiddle.net/MikeGrace/gsJyr/

I apologize for the lack of clarity, I hadn't realized how awful matching URLs was.

share|improve this question
    
Ahgrrrr! I miss my edit privileges! I you're going to restrict the game to one language perhaps you should tag it with that language. –  dmckee Feb 4 '11 at 5:25
    
What constitute a valid URL character? because I can simply use \w for everything Do you expect backreferences for different URL components? –  SHiNKiROU Feb 4 '11 at 5:49
1  
"A URI is a sequence of characters from a very limited set, i.e. the letters of the basic Latin alphabet, digits, and a few special characters," according to RFC 2396. –  RunnerRick Feb 4 '11 at 6:18
    
Mike: I guess there is still some clarification in order. As it stands now I can just use /:/ as the regular expression and match valid URIs and not match all your examples on the »Not match« list. As long as you're going that route it's simply the question: What is the shortest regular expression that will not match any of the example strings but still catch all URIs. –  Joey Feb 4 '11 at 9:10
1  
Just try to write a longer challenge with more details. –  user11 Feb 4 '11 at 22:06

4 Answers 4

up vote 1 down vote accepted
/.+\.\w\w.*/

doesn't match 3 strings that it shouldn't, matches almost anything else ;)
upd: it still doesn't match all 5

share|improve this answer

This one works:

var re = /(^|\s)((https?:\/\/)?[\w-]+(\.[\w-]+)+\.?(:\d+)?(\/\S*)?)/gi;

/*
(^|\s)                            : ensure that we are not matching an url 
                                    embeded in an other string
(https?:\/\/)?                    : the http or https schemes (optional)
[\w-]+(\.[\w-]+)+\.?              : domain name with at least two components;
                                    allows a trailing dot
(:\d+)?                           : the port (optional)
(\/\S*)?                          : the path (optional)
*/

Passes the tests at http://jsfiddle.net/9BYdp/1/

Also matches:

  • example.com. (trailing dot)
  • example.com:8080 (port)
share|improve this answer
    
Sweetness!!!!!!! –  Mike Grace Feb 4 '11 at 9:33
1  
Wouldn't you want to match a hostname with only one component as well (e.g. localhost)? –  RunnerRick Feb 4 '11 at 17:20
    
This allows spaces –  brenjt Nov 6 '13 at 17:52

This obviously doesn't do what you intend, but it meets your criteria:

 /.*/
  • "match all valid URLS that are for http and https."

    yep, definately will match.

  • "not worry about not matching for URL looking strings that aren't actually valid URLS like 'super.awesome/cool'"

    yeah, sure, there will be lots of false positives, but you said that doesn't matter.

  • be valid when run as a JavaScript regex

    sure as eggs works as you say it should.

If this result is NOT a right answer, then you need to be more selective with your criteria.

In order to be a rule that works as you intend, you actually do need to implement a full RFC compliant matcher, and a full RFC compliant matcher will "worry about not matching".

So, in terms of "permit not matching", you need to specify exactly which deviations from RFC are permissible.

Anything else, and this whole exercise is a sham, because people will just write whatever works for them, or how they like it, and sacrifice "making any sense" in favour of being short ( like I did ).

On your update

The most Naïve regex I can come up with that matches (and captures) all your pasted examples so far is:

/(\S+\.[^/\s]+(\/\S+|\/|))/g;

Its quite simple in nature, and assumes only 3 basic forms are possible.

x.y
x.y/
x.y/z 

z can be anthing not whitespace. x can be anything not whitespace. y can be anything that is neither whitespace or a '/' character.

There are a lot of things that will be valid to this rule, lots, but they'll at least look like a valid URI to a human, they just won't be specifications compatible.

eg:

hello.0/1  # valid 
1.2/1 # valid 
muffins://¥.µ/€  # probably valid

I think the sane approach is to extract things that are likely to be URI's, then validate them with something stricter, I'm looking at working out how to use the browsers URI class to validate them =).

But you can see the above reasoning working on this sample here: http://jsfiddle.net/mHbXx/

share|improve this answer
    
Thank you for the feedback. I have update the question. –  Mike Grace Feb 4 '11 at 8:23
    
He changed the question, but you can do better anyway with /:/ even after the edit :-) –  Joey Feb 4 '11 at 9:11
    
Thanks Mike =). I don't wish to compete myself in a more serious manner, the other suggestions are more useful, I just wished to point out the problem with the initial premise so that the question quality could improve =) –  Kent Fredric Feb 6 '11 at 5:02
    
Is it only me or is this matching "www .google .com"? –  Schiavini Aug 23 '12 at 14:36
/https?\:\/\/\w+((\:\d+)?\/\S*)?/

Try that.

I'm including the leading and trailing slashes that delimit the regular expression, so hopefully that doesn't hurt my character count!

This pattern limits the protocol to either http or https, allows for an optional port number, and then allows any character except whitespace.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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