假设您在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
包含整个段落文本。
还有一种方法可以捕获和使用捕获组中的数据,也就是()中的内容?
我相信您的目标如下。
ford
和http://example.com/ford/latest.html
之类的值中检索http://example.com/ford/some/other/data.html
的值。为此,此修改如何?
在您的脚本中,当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."
}
re
为null
。请小心。作为对Tanaike的补充,该答案旨在说明如果必须使用findText()
方法(例如同时更改元素属性,突出显示匹配范围等)可以做什么。
问题是“数据”现在是整个段落
嗯,这完全是由于提供的提示:
getElement()
的结果是Element
本身。 asText()
上的Element
的结果是Text
实例。 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
\w
,\s
等)传递给表达式string
,必须转义反斜杠(例如,将正确解析\\w
)。] >string[][]
以提取所有捕获组()参考