【问题标题】:Match filename and file extension from single Regex匹配来自单个正则表达式的文件名和文件扩展名
【发布时间】:2012-02-18 13:39:09
【问题描述】:

我确信这一定很容易,但我正在努力......

var regexFileName = /[^\\]*$/; // match filename
var regexFileExtension = /(\w+)$/; // match file extension

function displayUpload() {
    var path = $el.val(); //This is a file input
    var filename = path.match(regexFileName); // returns  file name
    var extension = filename[0].match(regexFileExtension); // returns extension

    console.log("The filename is " + filename[0]);
    console.log("The extension is " + extension[0]);
}

上面的函数工作正常,但我确信它必须可以通过引用 .match() 方法返回的数组的不同部分来使用单个正则表达式来实现。我试过组合这些正则表达式,但没有成功。

另外,我在示例中没有使用字符串对其进行测试,因为 console.log() 会转义文件路径中的反斜杠,这开始让我感到困惑 :)

【问题讨论】:

    标签: javascript jquery regex


    【解决方案1】:

    /^.*\/(.*)\.?(.*)$/g 后面第一组是你的文件名,第二组是扩展名。

    var myString = "filePath/long/path/myfile.even.with.dotes.TXT";
    var myRegexp = /^.*\/(.*)\.(.*)$/g;
    var match = myRegexp.exec(myString);
    alert(match[1]);  // myfile.even.with.dotes
    alert(match[2]);  // TXT
    

    即使您的文件名包含多个点或根本不包含点(没有扩展名),这也有效。
    编辑:
    这是 linux 的,windows 使用这个 /^.*\\(.*)\.?(.*)$/g (在 linux 目录分隔符是 / 在 windows 是 \

    【讨论】:

    • 这失败了'/tmp/myFile.txt'
    【解决方案2】:

    假设所有文件都有扩展名,您可以使用

    var regexAll = /[^\\]*\.(\w+)$/;
    

    那你就可以了

    var total = path.match(regexAll);
    var filename = total[0];
    var extension = total[1];
    

    【讨论】:

    • 我更喜欢 .net 正则表达式,但您不会错过第一个捕获组吗?
    • @rtpHarry:整个匹配(组 0)是文件名(包括扩展名),第一个捕获组(组 1)是扩展名。
    • 他需要文件名,而不是整个路径。
    • @Ademiban:我不这么认为。他希望得到与他现在的代码相同的结果,但在单个正则表达式中完成所有操作。
    【解决方案3】:

    为此,您可以在正则表达式中使用组:

    var regex = /^([^\\]*)\.(\w+)$/;
    var matches = filename.match(regex);
    
    if (matches) {
        var filename = matches[1];
        var extension = matches[2];
    }
    

    【讨论】:

    • 我更喜欢 .net 正则表达式,但您不会错过第一个捕获组吗?
    • 你是对的。我刚刚测试过,文档有点混乱:P
    • 您的代码之前是正确的,现在已损坏。如果只有一个捕获组,matches[2] 应该来自哪里?
    • 啊,是的,忘记了第一个捕获组。感谢您的提醒。
    【解决方案4】:

    我认为这是一种更好的方法,因为它只匹配有效的目录、文件名和扩展名。并且还对路径、文件名和文件扩展名进行分组。并且也适用于仅文件名的空路径。

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

    测试用例

    the/p0090Aath/fav.min.icon.png
    the/p0090Aath/fav.min.icon.html
    the/p009_0Aath/fav.m45in.icon.css
    fav.m45in.icon.css
    favicon.ico
    

    输出

    [the/p0090Aath/][fav.min.icon][png]
    [the/p0090Aath/][fav.min.icon][html]
    [the/p009_0Aath/][fav.m45in.icon][css]
    [][fav.m45in.icon][css]
    [][favicon][ico]
    

    【讨论】:

      【解决方案5】:

      这甚至可以识别/home/someUser/.aaa/.bb.c

      function splitPathFileExtension(path){
          var parsed = path.match(/^(.*\/)(.*)\.(.*)$/);
          return [parsed[1], parsed[2], parsed[3]];
      }
      

      【讨论】:

        【解决方案6】:

        我知道这是一个老问题,但这是另一个可以处理名称中的多个点以及根本没有扩展名(或只是 '.' 的扩展名)的解决方案:
        /^(.*?)(\.[^.]*)?$/

        一次拿一块:
        ^
        锚定到字符串的开头(以避免部分匹配)

        (.*?)
        匹配任意字符.,0次或多次*,懒惰?(如果后面的可选扩展可以匹配就不要全部抓取),并将它们放入第一个捕获组() .

        (\.
        使用( 为扩展启动第二个捕获组。该组以文字 . 字符开头(我们使用 \ 转义,因此 . 不会被解释为“匹配任何字符”)。

        [^.]*
        定义一个字符集[]。通过指定这是一个反转字符集^ 来匹配集合中的字符not。匹配 0 个或多个非. 字符以获取文件扩展名* 的其余部分。我们以这种方式指定它,这样它就不会在早期与foo.bar.baz 等文件名匹配,错误地给出一个包含多个点的扩展名.bar.baz 而不仅仅是.baz. 不需要在 [] 中转义,因为所有内容(^ 除外)都是字符集中的文字。

        )?
        结束第二个捕获组) 并指出整个组是可选的?,因为它可能没有扩展名。

        $
        锚定到字符串的末尾(再次避免部分匹配)

        如果您使用的是 ES6,您甚至可以使用破坏来获取 1 行中的结果:
        [,filename, extension] = /^(.*?)(\.[^.]*)?$/.exec('foo.bar.baz'); 文件名为'foo.bar',扩展名为'.baz'
        'foo' 给出'foo' and ''
        'foo.' 给出'foo''.'
        '.js' 给出'''.js'

        【讨论】:

          【解决方案7】:

          (?!\w+).(\w+)(\s)

          找到一个或多个单词\w+,否定(?! ),这样单词就不会显示在结果中,指定分隔符.,找到第一个单词(\w+)并忽略在可能的空格 (\s) 之后的单词

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-05
            • 2013-10-16
            • 2019-07-30
            • 1970-01-01
            相关资源
            最近更新 更多