【问题标题】:Get path element from URL using findText()使用 findText() 从 URL 获取路径元素
【发布时间】:2020-04-24 20:24:17
【问题描述】:

假设您在 Google 文档中有以下段落,并且您想从与汽车相关的 url 中提取元素。

一些包含一些数据的段落有一个 url http://example.com/ford/some/other/data.html。还有另一个链接:http://example.com/ford/latest.html

我正在寻找的是从这一段中拉出“福特”,以便我可以使用它。为了简单起见,我知道段落编号,我将在下面将其称为“1”。

我试过了:

function getData() {
  var paragraphs = DocumentApp.getActiveDocument().getBody().getParagraphs();
  var element = paragraphs[1];
  var re = element.findText('http://example.com/([a-z])+/');
  var data = re.getElement().asText().getText();
  Logger.log(data);
}

问题在于data 包含整个段落文本。

还有没有办法从捕获组中捕获和使用数据,也就是 () 中的内容?

【问题讨论】:

    标签: regex google-apps-script google-docs-api


    【解决方案1】:

    我相信你的目标如下。

    • 您想使用 Google Apps 脚本从 http://example.com/ford/latest.htmlhttp://example.com/ford/some/other/data.html 等值中检索 ford 的值。
    • 这些值被放入 Google 文档中。

    对于这个,这个修改怎么样?

    修改点:

    在您的脚本中,当element.findText('http://example.com/([a-z])+/') 有值时,re.getElement().asText().getText() 是段落的文本。在这种情况下,发现element.findText()模式下的文本包含在element中。使用它,如何从re.getElement().asText().getText() 中检索ford 之类的值?

    修改脚本:

    从:
    var data = re.getElement().asText().getText();
    Logger.log(data);
    
    到:
    if (re) {
      var data = [...re.getElement().asText().getText().matchAll(/http:\/\/example\.com\/([\w\S]+?)\//g)];
      console.log(data.map(([,e]) => e));
    } else {
      throw "Not match."
    }
    
    • 当段落没有与您的正则表达式匹配的值时,renull。请小心。

    注意:

    • 请使用启用 V8 的脚本。

    参考:

    【讨论】:

      【解决方案2】:

      作为对 Tanaike 的补充,此答案旨在说明如果您必须使用 findText() 方法(例如同时更改元素属性、突出显示匹配范围等)可以做什么。


      问题是“数据”现在是整个段落

      嗯,这正是由于提供的说明:

      1. getElement() 的结果是Element 本身。
      2. asText()Element 上的结果是Text 实例。
      3. getText()Text 上的结果是,引用文档:

      元素的内容作为文本字符串


      有没有办法捕获和使用数据

      在撰写本文时,findText() 似乎不可能按照 docs 引用,以供后代参考:

      不完全支持 JavaScript 正则表达式功能的子集,例如捕获组和模式修饰符。


      怎么办?

      找到匹配项后,findText() 会返回一个 RangeElement 实例,该实例有两个感兴趣的方法:getStartOffset()getEndOffsetInclusive()。这些方法的返回值指向元素文本内容的字符索引。因此,可以通过substring()方法(或slice())提取匹配的子字符串。

      您可以使用findText()方法的from参数递归迭代匹配结果以获得所有匹配范围。

      /**
       * @summary pattern wrapper
       * @param {string} linkPattern
       * @param {RegExp} [infoPattern]
       */
      const matchText = (linkPattern, infoPattern) => 
      
        /**
         * @summary finds links in text elements
         * @param {GoogleAppsScript.Document.Paragraph} elem
         * @param {string} [text]
         * @param {GoogleAppsScript.Document.RangeElement} [from]
         * @param {string[]} [matches]
         * @returns {string[][]}
         */ 
        (elem, text = elem.getText(), from, matches = []) => {
      
          const match = from ? 
            elem.findText(linkPattern, from) : 
            elem.findText(linkPattern);
      
          if(match) {
             const rangeStart = match.getStartOffset();
             const rangeEnd = match.getEndOffsetInclusive();
      
             const link = text.substring( rangeStart, rangeEnd + 1 );
             const [ full, ...groups ] = link.match( infoPattern );
      
             matches.push(groups);
      
             return matchText(linkPattern, infoPattern)(elem, text, match, matches);
          }
      
          return matches;
        }
      

      用于测试的驱动脚本:

      function findText() {
        const doc = getTestDoc(); //gets doc somehow, not provided here
      
        const body = doc.getBody();
      
        const par = body.appendParagraph("Some paragraph with some data in it https://example.com/ford/some/other/data.html.\nThere is another link also here https://example.com/ford/latest.html.");
      
        const pattern = 'http(?:s)*:\/\/(?:www\.)*example\.com\/\\w+';
        const targetPattern = /\/(\w+)$/;
      
        const results = matchText(pattern,targetPattern)(par);
      
        Logger.log(results); //[[ford], [ford]]
      }
      

      备注

      1. 好奇的观察:显然,要将标记(\w\s 等)传递给表达式 string,必须转义反斜杠(例如 \\w 将被解析正确)。
      2. 请注意,上面的解决方案返回一个string[][] 以提取所有捕获组()
      3. 上面的示例代码是为 V8 运行时设计的。

      参考文献

      1. getElement()spec
      2. asText()spec
      3. getText()spec
      4. findText()spec
      5. getStartOffset()spec
      6. getEndOffsetInclusive()spec
      7. substring() docs 在 MDN 上

      【讨论】:

        猜你喜欢
        • 2011-04-06
        • 1970-01-01
        • 2014-09-15
        • 1970-01-01
        • 2021-12-22
        • 2019-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多