这个正则表达式有什么问题?如何获取URL的哈希部分?

3

我正在尝试从URL中获取哈希的第一部分(在#和/、?或字符串结尾之间的部分)。

到目前为止,我得出了以下结果:

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

我原本期望收到“哈希”。
我追踪问题到了。
/#(.*)[$]/
r2.exec('http://localhost/item.html#hash')
null

任何想法是什么出了问题?
6个回答

3

在字符类中,如果你想匹配美元符号($)本身而不是行尾,就应该写成[$]

注意不要随意写成[$]

/#(.*)$/

代码:

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

输出:

["#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

在进行以上更改后,您将得到/#(.*?)(\?|\/|$)/

请忽略“/”和“?”之后的部分。 - opensas
@opensas 无论如何更新了。正则表达式与被接受的答案非常相似 :)。 - Anirudh Ramanathan

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

当$出现在[](字符类)中时,它代表的是字面上的“$”字符,而不是输入/行的结尾。实际上,你的[\?|\/|$]部分等同于[?/$|],可以匹配4个特定字符(包括管道符)。

请改用此代码 (JSFiddle)

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

1
为什么要使用正则表达式?可以这样做(几乎不需要正则表达式):
var a = document.createElement('a');
a.href = 'http://localhost/item.html#hash/foo?bar';
console.log(a.hash.split(/[\/\?]/)[0]); // #hash

仅供参考,如果你正在使用的是 node.js

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

2
你怎么确定 OP 在浏览器中? - Lyn Headley
1
没有什么可以让我确信,这只是纯粹的猜测。我喜欢玩火。无论如何,如果没有其他选择,我会选择正则表达式作为工具。所以我从另一个角度看待了这个问题。 - dan-lee
不要忘记我也试图摆脱任何“/”或“?”后面的部分。 - opensas

1
我使用http://regexpal.com/测试我的正则表达式。 你在这里的问题是你的正则表达式需要一个/。所以它不能与http://localhost/item.html#hash一起工作,但可以与http://localhost/item.html#hash/一起工作。
尝试这个:
r = /#([^\?|\/|$]*)/

根据我收到的评论,$ 在字符类中会被按字面意义匹配... - opensas
是的,你说得对。如果你不想匹配$字符,你应该将它放在[]部分之外。像这样:/#([^?|/]*)$/ - Magus

1

在字符类中不能使用字符串结束标记$。你最好匹配不是/?的字符,像这样:

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

这正是我找到的解决方案。我觉得它非常简单而优雅。 - opensas

0
我找到了一个似乎有效的正则表达式。
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"]

无论如何,我仍然不明白为什么原来的那个不起作用


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接