【问题标题】:How to extract URL from Link in Google Sheets using a formula?如何使用公式从 Google 表格中的链接中提取 URL?
【发布时间】:2016-05-15 19:41:44
【问题描述】:

我从一个网站复制了一系列超链接并将它们粘贴到谷歌表格中。这些值显示为链接文本,而不是超链接公式,并且仍然正确链接。对于每一行,我试图仅提取 URL(不是友好文本)并将其插入到相邻列中。这怎么能用公式来完成?

例如:

=SOMEFUNCTION(cellThatHoldsLink, returnedURLOnly)

This and similar scenarios 不适用,因为粘贴的数据不是公式。 我将接受脚本 (GAS) 解决方案或任何解决方案,但如果可以使用公式完成,我会更喜欢。我发现了几十个 HYPERLINK 操作脚本,但在这个特定的场景中什么都没有,甚至没有找到如何访问持有该 url 的属性。谢谢。

【问题讨论】:

  • 提供几个真实的单元格内容示例。然后有人可以测试输出。
  • 桑迪,这是一个例子:docs.google.com/spreadsheets/d/…
  • 你是不是先在那个地方粘贴了一些链接或超链接,然后删除并再次粘贴?
  • 我用鼠标直接从网页中选择了文本,右键单击并选择复制,然后将其粘贴到工作表中。如果有另一种复制数据的方法可以传输一些需要的属性,我也愿意。
  • 是的 - 我每天都使用 linkclump - 它是一个漂亮的 chrome 插件 - 或者如果你分享你从中获得链接的源 URL - 我会在你的工作表上向你展示一个很酷的技巧

标签: google-sheets formula


【解决方案1】:

在 2020 年的一些更新之后,我在互联网上找到的所有代码都被破坏了,所以这是我的贡献:

/** 
 * Returns the URL of a hyperlinked cell, if it's entered with control + k. 
 * Author: @Frederico Schardong based on https://support.google.com/docs/thread/28558721?hl=en&msgid=28927581 and https://github.com/andrebradshaw/utilities/blob/master/google_apps/convertHiddenLinks.gs 
 * Supports ranges
 */
function linkURL(reference) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var formula = SpreadsheetApp.getActiveRange().getFormula();
  var args = formula.match(/=\w+\((.*)\)/i);
  try {
    var range = sheet.getRange(args[1]);
  }
  catch(e) {
    throw new Error(args[1] + ' is not a valid range');
  }

  var formulas = range.getRichTextValues();
  var output = [];
  for (var i = 0; i < formulas.length; i++) {
    var row = [];
    for (var j = 0; j < formulas[0].length; j++) {
      row.push(formulas[i][j].getLinkUrl());
    }
    output.push(row);
  }
  return output
}

【讨论】:

  • 这太棒了!非常感谢!我仍然有一个边缘情况要解决,我在同一个“公式”中有多个链接(公式 [0].length == 1)。你知道如何解决这个问题吗?
  • 终于找到了解决方案,使用 getRuns() 完成了这项工作。我的“特定”脚本在这里:gist.github.com/glureau/833d83099cb74efc937f9afddba2cca4 你只需要调整想要的格式
  • 我确认。这与 Google 表格中粘贴的超链接的预期完全一样。谢谢!
  • 对于嵌入式 URL(与 HYPERLINK=... 不同),我首先使用此插件 extract-urls.contributor.pw 转换它们,然后使用此 linkURL 获取实际 URL
  • @Kikiwa 的要点在 2021 年最适合我
【解决方案2】:

如果您的超链接在另一个单元格中指定为公式 - 例如,假设单元格 A1 包含公式 =HYPERLINK("https://www.wikipedia.org/","Wikipedia"),您可以使用正则表达式提取链接文本。您需要做的就是:

=REGEXEXTRACT(FORMULATEXT(A1),"""(.+)"",")

这个公式将产生结果:

https://www.wikipedia.org/

不需要自定义函数。

【讨论】:

  • =REGEXEXTRACT(FORMULATEXT(A1),"""(.+?)""") 更好,因为链接文本是可选参数,可能没有逗号,而且 REGEXEXTRACT 只返回第一个匹配项
  • 非常棒,当超链接使用=hyperlink("https ...," ...") 创建时效果很好,但不幸的是,当超链接从其他地方粘贴时,这不起作用。是否可以将粘贴的超链接转换为使用公式 =hyperlink() 的超链接?也许有一个宏?
  • 1.以上=REGEXEXTRACT() 对于=hyperlink() 的提取来说是精彩,谢谢@Jordan。 2 @AdolfoCorrea - 您是否都收到了对上述问题的回复/回答/反馈?我也很感兴趣。
  • @JohnnyUtahh 我还没有找到解决这个问题的方法。如果你这样做,请在这里评论。如果我找到解决这个问题的方法,我也会这样做
【解决方案3】:

内置的SpreadsheetApp 服务似乎不支持提取此类 URL,但“Advanced” Sheets 服务支持。

根据Google's instructions开启Advanced Sheets服务,然后试试这段代码:

function onOpen() {
  var menu = SpreadsheetApp.getUi().createMenu("Extract URLs");
  menu.addItem("Process =EXTRACT_URL(A1) formulas", "processFormulas");
  menu.addToUi();
}

function EXTRACT_URL() {
  return SpreadsheetApp.getActiveRange().getFormula();
}

function processFormulas() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getActiveSheet();
  var rows = sheet.getDataRange().getFormulas();
  for (var r = 0; r < rows.length; r++) {
    var row = rows[r];
    for (var c = 0; c < row.length; c++) {
      var formula = row[c];
      if (formula) {
        var matched = formula.match(/^=EXTRACT_URL\((.*)\)$/i);
        if (matched) {
          var targetRange = matched[1];
          if (targetRange.indexOf("!") < 0) {
            targetRange = sheet.getName() + "!" + targetRange;
          }
          var result = Sheets.Spreadsheets.get(spreadsheet.getId(), {
            ranges: targetRange,
            fields: 'sheets.data.rowData.values.hyperlink'
          });
          try {
            var value = result.sheets[0].data[0].rowData[0].values[0].hyperlink;
            sheet.getRange(r + 1, c + 1).setValue(value);
          } catch (e) {
            // no hyperlink; just ignore
          }
        }
      }
    }
  }
}

这会创建一个名为EXTRACT_URL 的custom function,您应该在调用它时引用包含链接的单元格;例如,=EXTRACT_URL(B3)。

不幸的是,它不能立即工作,因为高级表格服务can't be used directly 通过自定义函数。因此,该脚本在电子表格菜单栏中添加了一个名为“Extract URLs”的菜单,其中一个菜单项标记为“Process =EXTRACT_URL(A1) formulas”。当你点击它时,它会将EXTRACT_URL 函数的所有使用替换为 URL 本身。

【讨论】:

  • 这可行,但如果一次处理太多,我会收到错误“配额'ReadGroup'的令牌不足并限制服务'sheets.googleapis.com'的'USER-100s'”。另外值得注意的是,这是一次性操作,因为它将公式替换为结果。
  • 是的,这行得通!但是由于已经提到的配额问题,所以速度很慢。怎么解决?
  • @JoeErcolino 您可以通过更新代码以获取多个值然后写入工作表一次来加快速度。这样做,我能够在 0.793 秒内获取、应用额外处理并打印 184 个值。
【解决方案4】:

这可以通过将链接粘贴到或使用 按钮自动创建的链接来完成,方法是转到工具 -> 脚本编辑器并创建以下脚本:

函数 GETLINK(输入){

return SpreadsheetApp.getActiveSheet().getRange(input).getRichTextValue().getLinkUrl();

}

如果单元格 A1 有链接,您需要将其引用为 =GETLINK("A1") 如果您有很多链接,这不会动态更新,因此请使用=GETLINK(cell("Address",A1)) 来解决这个问题。

感谢 reddit 上的 morrisjr1989。

【讨论】:

  • 这个 GETLINK 是今天唯一对我有帮助的东西。但是,由于我的链接值都在 B 列中,我最终使用了 =GETLINK("B"&ROW())。 (想了很久,为什么,例如,=GETLINK(B2) 不想直接工作。)
  • 这引发了一个异常 :( 异常:参数不能为空:a1Notation GETLINK @ Code.gs:3
  • @cmantas A1 只是一个例子。您需要使用具有链接的单元格的地址。
【解决方案5】:

您可以使用 importxml 来拉入整个数据表及其内容:

=IMPORTXML(A1,"//tr")

在它旁边,我们在标签中提取了 url 字符串

=IMPORTXML(A1,"//tr/td[1]/a/@href")

最后将字符串与原始域连接起来以创建超链接

=ARRAYFORMULA("http://www.bnilouisiana.com/"&INDIRECT("A2:A"&COUNTA(A2:A)))

【讨论】:

  • 我试过这个,我在单元格中只有 URL,没有超链接公式,但是单元格是一个链接。我将上面粘贴到新工作表中,它导入了所有数据,但只是使用字符串“url”而不是链接。单元格的小例子在这里docs.google.com/a/fuzion.co.nz/spreadsheets/d/…
  • oop 点击“添加评论”到很快。你认为上面的方法应该在这种情况下工作吗?
  • 你还没有分享文档@petednz-fuzion
  • 感谢您尝试协助并确认这是“没有希望”,因为“它们不是字符串网址”引用您的 PM。
  • 第二个公式。但我也遇到过说这个功能有时不起作用的帖子
【解决方案6】:

如果您乐于使用 Google Apps 脚本,请使用以下函数从文本中获取超链接。当您通过单元格时,您应该使用双引号发送。例如:=GETURL("A4") 获取 A4 超链接。

function GETURL(input) {
  var range = SpreadsheetApp.getActiveSheet().getRange(input);
  var url = /"(.*?)"/.exec(range.getFormulaR1C1())[1];
  return url;
}

例如参考here。

编辑:忽略此答案。这仅在 url 在单元格中链接时才有效。

【讨论】:

  • 如果您查看他的示例,这将不起作用 - 链接不是超链接公式 - 奇怪的是,它只是带有链接的文本,但没有可见的“链接公式”
  • 哦!知道了!抱歉,这不适用于他的示例。
  • @iamtoc 我在上面评论过,如果您分享一个示例链接,从中获取网址,我将向您展示通过 xpath 自动提取所有这些网址的公式
  • @iamtoc 在您的示例文档中添加了一张表格 - 并将 xml 提取内容放在那里 - 我只能假设它不仅是您要提取的一个页面 - 如果您有第二个链接,所以我可以看到网址格式是什么我们可以自动为您拉入所有页面
  • 还在公式上添加了 4 个 cmets 以进行澄清
【解决方案7】:

所以,通过一些研究,我可以看到谷歌表格中有两种类型的链接

  1. 超链接(公式如=HYPERLINK=("www.google.com"))
  2. “嵌入式”链接(您无法查看或编辑公式)

对于第一种,您可以直接使用@frederico-schardong 的linkURL。

对于第二种,您可以先使用extract URLs 插件,然后再使用linkURL。

【讨论】:

    【解决方案8】:

    找到了一个有效的答案on Google Groups(特洛伊):

    1. 发布您的电子表格(复制网址)
    2. 创建一个新的电子表格并使用 IMPORTXML 函数(将 url 替换为您在第 1 步中获得的 url)
    3. 您将获得数据 - 然后您可以将值复制并粘贴到您需要的位置
    4. 取消发布电子表格(如果您不想公开)

    可以通过脚本完成,但我现在没有时间。 :)

    【讨论】:

      【解决方案9】:

      我能够以非常简单的方式为 Jotform 解决这个问题。

      我希望在查询中包含“编辑”链接,但它只会给我“编辑提交”文本。

      但是,我注意到我在 R 列中有表单 ID。然后我可以复制 JotForm 链接并将其与单元格引用“https://www.jotform.com/edit/”&R2

      【讨论】:

        【解决方案10】:

        Ryan Tarpine 的例子帮助很大。谢谢!

        使用下面的代码,您可以用选定范围内的标准 HYPERLINK 公式替换所有嵌入的链接。请注意,必须激活高级表格服务。

        function embeddedURLsToHyperlink() {
          var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
          var sheet = spreadsheet.getActiveSheet();
          var rows = sheet.getActiveRange().getValues();
          var z = sheet.getActiveRange().getRowIndex();
          var s = sheet.getActiveRange().getColumn();
        
          for (var r = 0; r < rows.length; r++) {
            var row = rows[r];
            for (var c = 0; c < row.length; c++) {
              var val = row[c];
              if (val) {
                var targetRange = sheet.getRange(r+z, c+s).getA1Notation();
                var result = Sheets.Spreadsheets.get(spreadsheet.getId(), {
                  ranges: sheet.getName() + "!" + targetRange,
                  fields: 'sheets.data.rowData.values'
                });
                if (result.sheets[0].data[0].rowData[0].values[0].hyperlink) {
                  var url = result.sheets[0].data[0].rowData[0].values[0].hyperlink;
                  var text = result.sheets[0].data[0].rowData[0].values[0].effectiveValue.stringValue;
                  sheet.getRange(r + z, c + s).setFormula('=HYPERLINK("' + url + '","' + text + '")');
                }
              }
            }
          }
        }
        

        如果你想处理整个表格,请将第 4-6 行替换为以下代码:

        var rows = sheet.getDataRange().getValues();
        var z = 1;
        var s = 1;
        

        【讨论】:

          【解决方案11】:

          您可以创建一个宏“ExtractURLs”,然后使用以下代码对其进行编辑,该代码解析活动单元格中一致的文本样式块,尝试检索 URL,并将它们粘贴到相邻单元格中。

          
              function ExtractURLs() {
                
                var spreadsheet = SpreadsheetApp.getActive();
              
                var richTextCell = SpreadsheetApp.getActiveRange().getRichTextValue();
              
                var richTextStrings = richTextCell.getRuns();
                
                var linksStr = "";
                var linkCell = spreadsheet.getCurrentCell()
                var link = "";
                var richTextString = "";
              
                for (var x=0; x < richTextStrings.length; x++)
                {
                  richTextString = richTextStrings[x].getText();
                  
                  Logger.log(richTextString);
              
                  link = richTextStrings[x].getLinkUrl();
                  Logger.log(link);
              
                  if (link != null)
                  {
                   linksStr += link;
                   linksStr += ', '; 
                  }  
                }  
              
                var targetCell = linkCell.offset(0, 1).activate();
                targetCell.setValue(linksStr.substr(0,linksStr.length-2));
              };
          
          

          【讨论】:

            【解决方案12】:

            快速的方法如果单元格行有限--->

            1. 只需右键单击单元格并单击编辑链接
            2. 删除文本并单击应用
            3. 对后面的每个单元格使用 f4

            如果您对此有更多要求,或者可以通过选择单元格来完成,请。告诉我

            【讨论】:

            • 但是你也会丢失链接文本
            • 这里的主要问题是 F4 会覆盖当前单元格上的第一个 url 地址,而不是根据需要删除链接名称。
            猜你喜欢
            • 2015-11-20
            • 2021-05-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-06-03
            • 1970-01-01
            • 2021-01-26
            • 1970-01-01
            相关资源
            最近更新 更多