使用 findText() 从 URL 获取路径元素
Get path element from URL using findText()
假设您在 Google 文档中有以下段落,并且您想从与汽车相关的 url 中提取该元素。
一些包含一些数据的段落有一个 url http://example.com/ford/some/other/data.html. There is also another link: 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
包含整个段落文本。
还有没有一种方法可以捕获和使用来自捕获组的数据,也就是 () 中的内容?
我相信你的目标如下。
- 您想使用 Google Apps 脚本从
http://example.com/ford/latest.html
和 http://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."
}
- 当段落没有匹配您的正则表达式的值时,
re
为 null
。请注意。
注:
- 请使用启用 V8 的脚本。
参考:
作为 Tanaike 的补充,此答案旨在展示如果您必须使用 findText()
方法(例如同时更改元素属性、突出显示匹配范围等)可以做什么。
问题是"data"现在是整段
嗯,这完全是由于提供的说明:
getElement()
的结果是 Element
本身。
asText()
在 Element
上的结果是 Text
实例。
getText()
在 Text
上的结果是,引用文档:
the contents of the element as text string
有没有办法捕获和使用数据
使用 findText()
在撰写本文时,根据 docs 似乎不可能,为后代引用它:
A subset of the JavaScript regular expression features are not fully supported, such as capture groups and mode modifiers.
怎么办?
找到匹配后,findText()
return 是一个 RangeElement
实例,它有两个感兴趣的方法:getStartOffset()
和 getEndOffsetInclusive()
。这些方法的 return 值指向元素文本内容的字符 indices。因此,可以通过 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]]
}
注释
- 奇怪的观察:显然,要将标记(
\w
、\s
等)传递给表达式 string
,必须 转义 反斜杠(例如 \w
将被正确解析)。
- 注意上面的解决方案return是一个
string[][]
来提取所有捕获组()
- 上面的示例代码专为 V8 运行时设计。
参考文献
假设您在 Google 文档中有以下段落,并且您想从与汽车相关的 url 中提取该元素。
一些包含一些数据的段落有一个 url http://example.com/ford/some/other/data.html. There is also another link: 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
包含整个段落文本。
还有没有一种方法可以捕获和使用来自捕获组的数据,也就是 () 中的内容?
我相信你的目标如下。
- 您想使用 Google Apps 脚本从
http://example.com/ford/latest.html
和http://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."
}
- 当段落没有匹配您的正则表达式的值时,
re
为null
。请注意。
注:
- 请使用启用 V8 的脚本。
参考:
作为 Tanaike 的补充,此答案旨在展示如果您必须使用 findText()
方法(例如同时更改元素属性、突出显示匹配范围等)可以做什么。
问题是"data"现在是整段
嗯,这完全是由于提供的说明:
getElement()
的结果是Element
本身。asText()
在Element
上的结果是Text
实例。getText()
在Text
上的结果是,引用文档:
the contents of the element as text string
有没有办法捕获和使用数据
使用 findText()
在撰写本文时,根据 docs 似乎不可能,为后代引用它:
A subset of the JavaScript regular expression features are not fully supported, such as capture groups and mode modifiers.
怎么办?
找到匹配后,findText()
return 是一个 RangeElement
实例,它有两个感兴趣的方法:getStartOffset()
和 getEndOffsetInclusive()
。这些方法的 return 值指向元素文本内容的字符 indices。因此,可以通过 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]]
}
注释
- 奇怪的观察:显然,要将标记(
\w
、\s
等)传递给表达式string
,必须 转义 反斜杠(例如\w
将被正确解析)。 - 注意上面的解决方案return是一个
string[][]
来提取所有捕获组() - 上面的示例代码专为 V8 运行时设计。
参考文献