从Google Apps脚本上的URL获取文件ID的最简单方法

时间:2013-05-30 15:23:07

标签: google-apps-script

以下是我要做的事情:给定Google文档网址,我想获取文档ID以在Google云端硬盘上创建副本。我知道我可以通过一些正则表达式或替换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的任何安全解决方案都适合我。

由于

10 个答案:

答案 0 :(得分:52)

DriveApp确实缺少getFileByUrl(以及此问题的文件夹)。您可能希望在Apps Script issue tracker上打开增强请求。

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

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

这个正则表达式适用于我尝试的任何谷歌网址:驱动文件夹和文件的网址,Fusion表格,电子表格,文档,演示文稿等。它只是在一个“看起来像”谷歌键的字符串中寻找任何东西。也就是说,任何足够大的字符串中只包含(谷歌键)有效字符。

此外,即使它直接收到ID而不是URL,它仍然有效。当您询问用户的链接时,这很有用,因为有些人可能会直接粘贴ID而不是网址,而且仍可以使用。

<强> - 修改

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

通过快速查看下面的建议,我推荐以下/[-\w]{25,}$/,因为它仍然非常简单,应该解决这些问题。

答案 1 :(得分:3)

网址是这样的,文件ID出现在这种模式中&#34; / d / XXXXXXXX /&#34;几乎所有GoogleDrive / Docs链接:
https://drive.google.com/file/d/0B3tB9BU9FRnpcTJmS2FoaktsQzA/view

使用以下功能,我们可以获得&#39; / d / fileid /&#39;然后截断&#39; / d /&#39;从开始和&#39; /&#39;从结束。

{{1}}

答案 2 :(得分:1)

上面没有提到的更多网址扩展可以包含ID。

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;
   }
 }

答案 3 :(得分:1)

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

否则它非常可靠,我认为这是这里提供的最优雅和强大的功能。

因此,在接受的答案上扩展,以下正则表达式将获取最后一次出现的字符串,该字符串至少包含25个字符,并且紧随其后的是非单词字符或连字号,并可选地后面跟相同类型的字符,以及结尾处可能出现的任何其他垃圾:

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

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

答案 4 :(得分:0)

我只是想根据两个给定的答案添加我创建的功能,因为它们都不是我想要的。

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

这会导致/d/之后的部分直到下一个/,这就是文档网址始终包含其ID的方式。如果没有找到匹配,那么我们只返回原始参数,假设是ID。

答案 5 :(得分:0)

Google Apps脚本中现已提供一种openByUrl方法。

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

因为你写过:

  

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

...假设您不需要ID 本身。通过网址获取工作表/文档/幻灯片/表单后,您可以对其进行复制。

答案 6 :(得分:0)

对于Python:

对于固定长度的Google驱动器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 :(得分:0)

要从网址电子表格中提取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);
}

答案 8 :(得分:0)

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

= mid({cellAddress},33,33)

示例:

= mid(A2,33,33)

答案 9 :(得分:0)

Henrique 建议的解决方案可能无法涵盖 Google Workspace 用户共享 Google Drive 文件的情况,其中域可能是文件 URL 的一部分。如果域名很长,则会捕获域名而不是文件 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;
}