opensas
opensas

Reputation: 63575

what's wrong with this regular expression? getting the hash part of an url

I´m trying to get the first part of a hash from a url (the part between the # and a /, a ? or the end of the string

So far now I came out with this:

r = /#(.*)[\?|\/|$]/

// OK
r.exec('http://localhost/item.html#hash/sub')
["#hash/", "hash"]

// OK
r.exec('http://localhost/item.html#hash?sub')
["#hash?", "hash"]

// WAT?
r.exec('http://localhost/item.html#hash')
null

I was expeting to receive "hash"

I tracked down the problem to

/#(.*)[$]/
r2.exec('http://localhost/item.html#hash')
null

any idea what could be wrong?

Upvotes: 3

Views: 778

Answers (6)

Anirudh Ramanathan
Anirudh Ramanathan

Reputation: 46778

You aren't supposed to write [$] (within a character class) unless you want to match the $ literally and not the end of line.

/#(.*)$/

Code:

var regex = /\#(.*)$/;
regex.exec('http://localhost/item.html#hash');

Output:

["#hash", "hash"]

Your regex: /#(.*)[\?|\/|$]/
  //<problem>-----^       ^-----<problem>

           | operator won't work within [], but within ()
           $ will be treated literally within  []
           .* will match as much as possible. .*? will be non-greedy

On making the above changes, you end up with /#(.*?)(\?|\/|$)/

Upvotes: 3

dan-lee
dan-lee

Reputation: 14502

Why Regex? Do it like this (nearly no regex):

var a = document.createElement('a');
a.href = 'http://localhost/item.html#hash/foo?bar';
console.log(a.hash.split(/[\/\?]/)[0]); // #hash

Just for the sake, if it is node.js you are working with:

var hash = require('url').parse('http://localhost/item.html#hash').hash;

Upvotes: 1

RichardTheKiwi
RichardTheKiwi

Reputation: 107796

r = /#(.*)[\?|\/|$]/

When $ appears in [] (character class, it's the literal "$" character, not the end of input/line. In fact, your [\?|\/|$] part is equivalent to just [?/$|], which matches the 4 specific characters (including pipe).

Use this instead (JSFiddle)

r = /#(.+?)(\?|\/|$)/

Upvotes: 3

Andrew Cooper
Andrew Cooper

Reputation: 32596

You can't use the $ end-of-string marker in a character class. You're probably better off just matching characaters that aren't / or ?, like this:

/#([^\?\/]*)/

Upvotes: 1

opensas
opensas

Reputation: 63575

I found this regular expression that seems to work

r = /#([^\/\?]*)/

r.exec('http://localhost/item.html#hash/sub')
["#hash", "hash"]

r.exec('http://localhost/item.html#hash?sub')
["#hash", "hash"]

r.exec('http://localhost/item.html#hash')
["#hash", "hash"]

Anyway, I still don't get why the original one isn't working

Upvotes: 0

Magus
Magus

Reputation: 15124

I use http://regexpal.com/ to test my regular expressions. Your problem here is that your regular expression wants a /. So it don't works with http://localhost/item.html#hash but it works with http://localhost/item.html#hash/

Try this one :

r = /#([^\?|\/|$]*)/

Upvotes: 1

Related Questions