【问题标题】:Easiest way to get file ID from URL on Google Apps Script从 Google Apps 脚本上的 URL 获取文件 ID 的最简单方法
【发布时间】:2013-05-26 06:10:02
【问题描述】:

这是我想要做的:给定一个 Google 文档 URL,我想获取文档 ID 以在 Google Drive 上创建一个副本。我知道我可以通过一些正则表达式或在 URL 上替换来实现这一点,但是由于有几种不同的形式可以在 URL 中表示同一个文档,所以我想找到一个通用的解决方案。

目前,这是我能想到的最好的:

function getFileIdFromUrl(url) {
  try {
    return getDocIdFromUrl(url);
  } catch (e) {
    return getSpreadsheetIdFromUrl(url);
  }
}

function getDocIdFromUrl(url) {
  var doc = null;
  try {
    doc = DocumentApp.openByUrl(url);
  } catch (e) {
    doc = DocumentApp.openByUrl(url + "/edit");
  }
  return doc.getId();
}

function getSpreadsheetIdFromUrl(url) {
  var spreadsheet = null;
  try {
    spreadsheet = SpreadsheetApp.openByUrl(url);
  } catch (e) {
    spreadsheet = SpreadsheetApp.openByUrl(url + "/edit");
  }
  return spreadsheet.getId();
}

function copy(url) { // may throw an exception if the URL is invalid or private
   var id = getFileIdFromUrl(url);
   var file = DriveApp.getFileById(id);
   file.makeCopy().setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.VIEW);
}

问题是我的解决方案只涵盖文档和电子表格,我想对任何上传的文件做同样的事情,例如:

https://docs.google.com/file/d/0B-FYu_D7D7x4REdtRVEzVH0eU0/edit

简而言之,我想要这样的东西:

DriveApp.getFileByUrl(url).makeCopy();

有人知道这是否可能吗?

任何从文件 URL 中提取文件 ID 的安全解决方案都适合我。

谢谢

【问题讨论】:

    标签: google-apps-script google-drive-api


    【解决方案1】:

    DriveApp 确实缺少getFileByUrl(以及与此相关的文件夹)。您可能想在Apps Script issue tracker 上提出增强请求。

    但我在我的脚本中所做的(因为这些 openByUrl 函数有些新)是使用正则表达式获取 id。像这样。

    function getIdFromUrl(url) { return url.match(/[-\w]{25,}/); }
    

    此正则表达式适用于我尝试过的任何 google url:文件夹和文件的 Drive url、Fusion Tables、Spreadsheets、Docs、Presentation 等。它只是在字符串中查找“看起来像”Google 密钥的任何内容。也就是说,任何足够大的字符串,其中只有(谷歌键)有效字符。

    此外,即使它直接接收 ID 而不是 URL,它也可以工作。当您向用户询问链接时,这很有用,因为有些人可能会直接粘贴 id 而不是 url,但它仍然有效。

    --编辑

    还有一些其他答案和 cmets 解决了一些我自己从未遇到过但可能会发生的边缘情况,例如尝试在嵌套文件夹 URL 上获取文件夹 ID,或者当您拥有 25 岁以上的 G-Suite 域时长字符。对于这些情况,您可能需要使用更严格的正则表达式。

    通过快速浏览下面的建议,我推荐以下/[-\w]{25,}(?!.*[-\w]{25,})/,因为它仍然非常简单,应该可以解决这些情况。

    【讨论】:

    • 我做了一些测试,看起来很棒!谢谢你。只是一个问题:这个数字 (25) 真的是 google docs id 的最小长度吗?
    • 这在任何地方都没有记录。我只是从各种文件中获取了一堆 URL,查看最短的一个并给予折扣以防万一:) 还检查了 url 的另一部分是否远程接近 25 个直字符(中间没有点,等),所以它不会与其他部分混淆。
    • 使用the regex suggested by aquadeep 不太可能进行不需要的匹配。然后使用 (group) 仅提取正则表达式的 ID 部分: url.match(/\/d\/(.{25,})\//)[1];
    • @Kenigmatic,不需要的匹配似乎不太可能,我更愿意相信 25 个字符作为基本长度,而不是 ID 总是以数字开头。我还认为我们可以相信 ID 将始终由数字、字母和连字符组成。为什么要使用点?
    • 刚刚发现您的编辑在最后一段中添加了一个不需要的“$”——不确定它应该在那里?猜猜我复制了哪一个并与之斗争:)。
    【解决方案2】:

    我有一张表格,我在其中将 URL 放入单元格中,然后将其拉入 App 脚本以执行其他操作(例如在文件夹中创建包含表格内容的文档)。

    我只是使用简单的str.split("/") 来提取 ID。有时,如果 URL 包含/u/0/,我只是将索引向下移动一点:

    if (sheet.getRange("D2").getValue().split("/")[4] === "u") {
      folderId = sheet.getRange("D2").getValue().split("/")[7];
    } else {
      folderId = sheet.getRange("D2").getValue().split("/")[5];
    }
    

    虽然它仅适用于两种给定的 Google Drive URL 格式。除了drive.google.com/drive/folders/#folderIddrive.google.com/drive/u/o/folders/#folderId,我还没有遇到很多其他人。

    【讨论】:

      【解决方案3】:

      Henrique 建议的解决方案可能无法涵盖 Google 云端硬盘文件由 Google Workspace 用户共享且域可能是文件网址的一部分的情况。如果域名很长,则会捕获域名而不是文件 URL。

      https://drive.google.com/a/thisisaverylongdomainname.org/file/d/1djf7XfuKx4Px55x7ahvMa5uznp3Ibe5vd7Y/view?usp=sharing
      

      Google Drive 生成​​的文件 ID 不包含句点 (.),因此修改后的 RegEx 可以防止捕获域名。

      function getFileIdFromDriveUrl(url) {
        var match = url.match(/([a-z0-9_-]{25,})[$/&?]/i);
        return match ? match[1] : null;
      }
      

      【讨论】:

        【解决方案4】:

        如果您在电子表格的单元格中有指向 Google Drive 文件的 URL,我相信您可以使用以下公式提取 fileID:

        =mid({cellAddress},33,33)

        例子:

        =mid(A2,33,33)

        【讨论】:

          【解决方案5】:

          要从 url 电子表格中提取 id,我使用下面的代码。它适用于 Google 电子表格和云端硬盘中的 Excel。也许也适用于其他文档。

          function getIdSheetFromUrl_(url)
          {
              var id = url.split('id=')[1];
              if(!id)
              {
                  id = url.split('/d/')[1];
                  id = id.split('/edit')[0]; // here we have the id
              }
              return DriveApp.getFileById(id);
          }
          

          【讨论】:

            【解决方案6】:

            对于 Python:

            对于固定长度的谷歌驱动器 ID,您可以使用:

            regex = "([\w-]){33}|([\w-]){19}"
            match = re.search(regex,url)
            

            Google 云端硬盘使用 33 个字符用于普通硬盘,19 个字符用于团队硬盘

            另一种不使用固定长度而是使用前置模式的方法:

            regex = "(?<=/folders/)([\w-]+)|(?<=%2Ffolders%2F)([\w-]+)|(?<=/file/d/)([\w-]+)|(?<=%2Ffile%2Fd%2F)([\w-]+)|(?<=id=)([\w-]+)|(?<=id%3D)([\w-]+)"
            
            match = re.search(regex,url)
            

            【讨论】:

              【解决方案7】:

              现在可以在 Google Apps 脚本中使用 openByUrl 方法。

              请参阅参考文档here for Sheetshere for Docshere for Slideshere for Forms

              因为你写了:

              我想获取文档 ID 以在 Google 云端硬盘上创建副本

              ...我假设您不需要 ID 本身。通过 URL 获取 sheet/doc/slide/form 后,可以进行复制。

              【讨论】:

                【解决方案8】:

                我没有足够的声誉来评论接受的答案,但是当驱动器 URL 包含域名并且域名超过 25 个字符时,来自 Henrique G. Abreu 的接受的答案失败(只是很难找到这一点:)

                否则它非常可靠,我认为是此处提供的最优雅和最强大的。

                因此,扩展已接受的答案,以下正则表达式将获得至少 25 个字符长的单词字符或连字符字符串的最后一次出现,其前面紧跟一个不是非单词字符的字符或连字符,并且可选地后跟相同类型的字符,以及末尾可能出现的任何其他垃圾:

                /.*[^-\w]([-\w]{25,})[^-\w]?.*/
                

                这失去了接受答案的特征,即仅在传递 ID 时它会起作用,但这不是我需要的用例。它适用于我测试过的文档和文件夹的所有不同类型的云端硬盘、文档、表格 URL。

                【讨论】:

                  【解决方案9】:

                  还有一些上面没有提到的可以包含 ID 的 URL 扩展。

                  https://drive.google.com/drive/folders/https://drive.google.com/open?id=https://drive.google.com/a/domain.edu.vn/folderview?id=

                  我想我会添加基于 this idea 的解决方案,涵盖上述两个扩展以及使用 /d/ 的扩展

                  function getIdFrom(url) {
                    var id = "";
                    var parts = url.split(/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/);
                    if (url.indexOf('?id=') >= 0){
                       id = (parts[6].split("=")[1]).replace("&usp","");
                       return id;
                     } else {
                     id = parts[5].split("/");
                     //Using sort to get the id as it is the longest element. 
                     var sortArr = id.sort(function(a,b){return b.length - a.length});
                     id = sortArr[0];
                     return id;
                     }
                   }
                  

                  【讨论】:

                    【解决方案10】:

                    我只是想根据两个给定的答案添加我创建的函数,因为两者都不是我想要的。

                    function templateIdFrom(url) {
                      var parts = url.match(/\/d\/(.+)\//);
                      if (parts == null || parts.length < 2) {
                        return url;
                      } else {
                        return parts[1];
                      }
                    }
                    

                    这将获取/d/ 之后的部分,直到下一个/,这就是文档 URL 始终包含其 ID 的方式。如果没有找到匹配项,那么我们只需返回原始参数,假定为 ID。

                    【讨论】:

                      【解决方案11】:

                      几乎所有 GoogleDrive/Docs 链接的 url 都是这样的,文件 ID 以这种模式“/d/XXXXXXXX/”出现:
                      https://drive.google.com/file/d/0B3tB9BU9FRnpcTJmS2FoaktsQzA/view

                      使用下面的函数,我们可以得到'/d/fileid/',然后从开头截断'/d/',从结尾截断'/'。

                      public static string getIdFromUrl(string url)
                      {
                          Regex r = new Regex(@"\/d\/(.+)\/", RegexOptions.IgnoreCase);
                          Match m = r.Match(url);
                          return m.ToString().TrimStart('/', 'd').Trim('/');
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2014-04-03
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-05-16
                        • 1970-01-01
                        • 2019-11-11
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多