Google apps script 从谷歌应用程序脚本上的URL获取文件ID的最简单方法

Google apps script 从谷歌应用程序脚本上的URL获取文件ID的最简单方法,google-apps-script,google-drive-api,Google Apps Script,Google Drive Api,下面是我试图做的:给定一个Google文档URL,我想获取文档ID,以便在Google Drive上创建一个副本。我知道我可以通过一些正则表达式或替换URL来实现这一点,但是由于URL中有几种不同的形式来表示同一文档,所以我想找到一个通用的解决方案 目前,这是我所能想到的最好的: function getFileIdFromUrl(url) { try { return getDocIdFromUrl(url); } catch (e) { return getSprea

下面是我试图做的:给定一个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);
}
问题是,我的解决方案只涉及文档和电子表格,我希望对任何上传的文件也这样做,例如:

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

DriveApp.getFileByUrl(url).makeCopy();
有人知道这是否可能吗

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


谢谢

DriveApp确实缺少一个
getFileByUrl
(以及与此相关的文件夹)。您可能希望在上打开增强请求

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

函数getIdFromUrl(url){返回url.match(/[-\w]{25,}/);} 这个正则表达式适用于我尝试过的任何google url:文件夹和文件、融合表、电子表格、文档、演示文稿等的驱动器url。它只查找字符串中“看起来”像google键的任何内容。也就是说,任何足够大的字符串中只有(google键)有效字符

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

--编辑

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


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

url类似于此,几乎所有GoogleDrive/Docs链接的文件id都以“/d/XXXXXXXX/”的模式显示:

使用下面的函数,我们可以得到“/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('/');
}

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

function templateIdFrom(url) {
  var parts = url.match(/\/d\/(.+)\//);
  if (parts == null || parts.length < 2) {
    return url;
  } else {
    return parts[1];
  }
}
函数模板IDFrom(url){
var parts=url.match(/\/d\/(.+)\/);
if(parts==null | | parts.length<2){
返回url;
}否则{
退货零件[1];
}
}

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

上面没有介绍的一些URL扩展可以包含ID

和 及

我想我应该添加我的解决方案,它构建在上面的两个扩展以及使用/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;
   }
 }

我没有足够的声誉对接受的答案发表评论,但当驱动器URL包含域名且域名超过25个字符时,Henrique G.Abreu接受的答案会失败(只是艰难地发现:)

除此之外,它一直非常可靠,我认为它是这里提供的产品中最优雅、最健壮的

因此,在接受的答案上展开,下面的正则表达式将得到最后出现的至少25个字符长的单词字符或连字符字符串,该字符串前面紧跟一个非单词字符或连字符的字符,后面可选地跟一个相同类型的字符,以及最后可能出现的任何其他垃圾:

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

这失去了被接受的答案的特性,即当只传递一个ID时它将工作,但是这不是我需要的用例。它适用于我测试过的文档和文件夹的所有不同类型的驱动器、文档、工作表URL。

一个
openByUrl
方法现在在谷歌应用程序脚本中可用

见参考文件,和

因为你写了:

我想获取文档ID,以便在Google Drive上创建副本

…我假设你不需要身份证本身。通过URL获取工作表/文档/幻灯片/表单后,您可以复制它。

对于Python:

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

regex = "([\w-]){33}|([\w-]){19}"
match = re.search(regex,url)
谷歌硬盘使用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)

regex=“(?要从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);
}

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

=mid({cellAddress},33,33)

例如:


=mid(A2,33,33)

Henrique建议的解决方案可能不包括Google Workspace用户共享Google驱动器文件的情况,其中域可能是文件URL的一部分。如果域名很长,则会捕获域名而不是文件URL

https://drive.google.com/a/thisisaverylongdomainname.org/file/d/1djf7XfuKx4Px55x7ahvMa5uznp3Ibe5vd7Y/view?usp=sharing
Google Drive生成的文件ID不包含句点(.),因此此修改的正则表达式可以防止捕获域名

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

我做了一些测试,看起来很棒!谢谢。只是一个问题:这个数字(25)真的是google docs ID的最小长度吗?这在任何地方都没有记录。我只是从各种文件中获取了一组URL,查看最短的一个,并提供折扣以防万一:)还检查了url的另一部分是否远程接近25个直字符(中间没有点等),因此不会与另一部分混淆。使用不太可能生成不需要的matc