What does the regex [^\s]*? mean?
<p>I am starting to learn python spider to download some pictures on the web and I found the code as follows. I know some basic regex.
I knew <code>\.jpg</code> means <code>.jpg</code> and <code>|</code> means <code>or</code>. what's the meaning of <code>[^\s]*?</code> of the first line?  I am wondering why using <code>\s</code>? 
And what's the difference between the two regexes?</p>

<pre><code>http:[^\s]*?(\.jpg|\.png|\.gif)
http://.*?(\.jpg|\.png|\.gif)
</code></pre>

<p>Alright, so to answer your first question, I'll break down <code>[^\s]*?</code>.</p>

<ul>
<li><p>The square brackets (<code>[]</code>) indicate a <a href="http://www.regular-expressions.info/charclass.html" rel="nofollow"><em>character class</em></a>. A character class basically means that you want to match anything in the class, at that position, one time. <code>[abc]</code> will match the strings <code>a</code>, <code>b</code>, and <code>c</code>. In this case, your character class is <em>negated</em> using the caret (<code>^</code>) at the beginning - this inverts its meaning, making it match anything <em>but</em> the characters in it.</p></li>
<li><p><code>\s</code> is fairly simple - it's a common shorthand in many regex flavours for "any whitespace character". This includes spaces, tabs, and newlines.</p></li>
<li><p><code>*?</code> is a little harder to explain. The <code>*</code> <a href="http://www.regular-expressions.info/repeat.html" rel="nofollow"><em>quantifier</em></a> is fairly simple - it means "match this token (the character class in this case) zero or more times". The <code>?</code>, when applied to a quantifier, makes it <em>lazy</em> - it will match as little as it can, going from left to right one character at a time.</p></li>
</ul>

<p>In this case, what the whole pattern snippet <code>[^\s]*?</code> means is "match any sequence of non-whitespace characters, including the empty string". As mentioned in the comments, this can more succinctly be written as <code>\S*?</code>.</p>

<p>To answer the second part of your question, I'll compare the two regexes you give:</p>

<pre><code>http:[^\s]*?(\.jpg|\.png|\.gif)
http://.*?(\.jpg|\.png|\.gif)
</code></pre>

<p>They both start the same way: attempting to match the protocol at the beginning of a URL and the subsequent colon (<code>:</code>) character. The first then matches any string that does not contain any whitespace and ends with the specified file extensions. The second, meanwhile, will match two literal slash characters (<code>/</code>) before matching any sequence of characters followed by a valid extension.</p>

<p>Now, it's obvious that both patterns are meant to match a URL, but both are incorrect. The first pattern, for instance, will match strings like</p>

<pre><code>http:foo.bar.png
http:.png
</code></pre>

<p>Both of which are invalid. Likewise, the second pattern will permit spaces, allowing stuff like this:</p>

<pre><code>http:// .jpg
http://foo bar.png
</code></pre>

<p>Which is equally illegal in valid URLs. A better regex for this (though I caution strongly against trying to match URLs with regexes) might look like:</p>

<pre><code>https?://\S+\.(jpe?g|png|gif)
</code></pre>

<p>In this case, it'll match URLs starting with both <code>http</code> and <code>https</code>, as well as files that end in both variations of <code>jpg</code>.</p>

python regex