正则表达式:从URL中捕获不带文件扩展名的文件名

12

我正在尝试创建一个Javascript正则表达式,用于捕获没有文件扩展名的文件名。 我已经阅读了其他帖子,其中“跳转到此页面:http://gunblad3.blogspot.com/2008/05/uri-url-parsing.html”似乎是默认答案。但这对我来说并不起作用。所以以下是我尝试让正则表达式工作的方法:

  1. 在主题字符串中查找最后一个正斜杠“/”。
  2. 捕获该斜杠和下一个句点之间的所有内容。

我能接近的是:/([^/]).\w$,在字符串'http://example.com/index.htm'上执行(exec())会捕获/index.htmindex

我需要它只捕获index

5个回答

50
var url = "http://example.com/index.htm";
var filename = url.match(/([^\/]+)(?=\.\w+$)/)[0];

让我们来看一下正则表达式:

[^\/]+    # one or more character that isn't a slash
(?=       # open a positive lookahead assertion
  \.      # a literal dot character
  \w+     # one or more word characters
  $       # end of string boundary
)         # end of the lookahead

这个表达式将收集所有不是斜杠的字符,紧接着(由于lookahead),后面跟着一个扩展名和字符串的结尾——换句话说,就是最后一个斜杠后面的所有内容直到扩展名。

或者,您可以完全不使用正则表达式,通过找到最后一个/和最后一个.的位置,使用lastIndexOf获取这些点之间的substring

var url = "http://example.com/index.htm";
var filename = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));

2
这个解决方案在文件名中有多个句点的情况下会失败,如果你需要测试,请参考@BGerrissen的解决方案。 - George Pantazis

20

已测试并可用,即使是没有文件扩展名的页面也可以。

var re = /([\w\d_-]*)\.?[^\\\/]*$/i;

var url = "https://dev59.com/sHA65IYBdhLWcg3wuRB8";
alert(url.match(re)[1]); // 'regex-capture-filename-from-url-without-file-extention'

url = 'http://gunblad3.blogspot.com/2008/05/uri-url-parsing.html';
alert(url.match(re)[1]); // 'uri-url-parsing'
([\w\d_-]*)获取一个包含字母、数字、下划线或破折号的字符串。
\.?也许后面紧跟着一个句点。
[^\\\/]*$但一直到最后肯定不会跟着斜杠或反斜杠。
/i忽略大小写。

这也可以捕获包含多个句点的文件名,而被接受的答案在这些情况下会失败。(例如:foo.global.js等)。 - George Pantazis

3

我觉得这些答案都不够有力。这是我的解决方案。

function getFileName(url, includeExtension) {
    var matches = url && typeof url.match === "function" && url.match(/\/?([^/.]*)\.?([^/]*)$/);
    if (!matches)
        return null;

    if (includeExtension && matches.length > 2 && matches[2]) {
        return matches.slice(1).join(".");
    }
    return matches[1];
}

var url = "http://example.com/index.htm";
var filename = getFileName(url);
// index
filename = getFileName(url, true);
// index.htm

url = "index.htm";
filename = getFileName(url);
// index
filename = getFileName(url, true);
// index.htm

// BGerrissen's examples
url = "https://dev59.com/sHA65IYBdhLWcg3wuRB8";
filename = getFileName(url);
// regex-capture-filename-from-url-without-file-extention
filename = getFileName(url, true);
// regex-capture-filename-from-url-without-file-extention

url = "http://gunblad3.blogspot.com/2008/05/uri-url-parsing.html";
filename = getFileName(url);
// uri-url-parsing
filename = getFileName(url, true);
// uri-url-parsing.html

// BGerrissen fails
url = "http://gunblad3.blogspot.com/2008/05/uri%20url-parsing.html";
filename = getFileName(url);
// uri%20url-parsing
filename = getFileName(url, true);
// uri%20url-parsing.html

// George Pantazis multiple dots
url = "http://gunblad3.blogspot.com/2008/05/foo.global.js";
filename = getFileName(url);
// foo
filename = getFileName(url, true);
// foo.global.js

// Fringe cases
url = {};
filename = getFileName(url);
// null
url = null;
filename = getFileName(url);
// null

为了符合原问题,缺省行为是排除扩展名,但可以很容易地反转。

2
你可以尝试使用这个正则表达式:
([^/]*)\.[^.]*$

2

试试这个正则表达式。它甚至可以处理带有多个句点的文件名。

最初的回答

(?<=\/)[^\/]*(?=\.\w+$)

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