[使用findText()从URL获取路径元素

问题描述 投票:0回答:2

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

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

我正在寻找的是从本段中删除“ ford”,以便我可以使用它。为了简单起见,我知道该段号,下面我将其称为“ 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
2个回答
1
投票

我相信您的目标如下。

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

为此,此修改如何?

修改点:

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

修改的脚本:

从:
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的情况下使用脚本。

参考:


0
投票

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


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

嗯,这完全是由于提供的提示:

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

元素的内容为文本字符串


有没有一种捕获和使用数据的方法

在撰写本文时,findText()似乎无法按照docs引用,以供后代引用:

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


该怎么办?

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

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

/**
 * @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]]
}

Notes

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

  1. [getElement() spec
  2. [asText() spec
  3. [getText() spec
  4. [findText() spec
  5. [getStartOffset() spec
  6. [getEndOffsetInclusive() spec
  7. MDN上的[substring() docs
© www.soinside.com 2019 - 2024. All rights reserved.