使用 Google 应用程序脚本将文本替换为超链接
Replace text with hyperlink using Google apps script
我需要在不影响超链接的情况下替换单词(必须为替换的单词保留超链接),那些没有超链接的替换必须以常规方式进行。
Here is the link of the coded Docs
我试过
function run() {
var findtext = "Search";
var replacetext = "Replacer";
var body = DocumentApp.getActiveDocument().getBody();
var foundElement = body.findText(findtext);
while (foundElement != null) {
var foundText = foundElement.getElement().asText();
var startOffset = foundElement.getStartOffset();
var endOffsetInclusive = foundElement.getEndOffsetInclusive();
var hyperlink = foundText.getLinkUrl(0);
foundText.insertText(0, findtext);
foundText.setLinkUrl(startOffset + findtext.length, endOffsetInclusive + findtext.length, hyperlink);
foundText.deleteText(startOffset + findtext.length, endOffsetInclusive + findtext.length)
foundElement = body.findText(findtext, foundElement);
}
}
主要问题是将 findText
的结果视为一个词。
这很棘手,因为您无法获得“单词”元素。你必须:
- 取整段元素即
findText
returns。这包含搜索结果。
- 获取找到的单词的开头和结尾的索引值。
- 获取该索引处的超链接
- 删除这些索引之间的文本
- 插入新文本,然后为超链接分配新索引。
例如:
foundText.insertText(0, findtext)
在结果所在元素的 start 处插入您要查找的文本,即“搜索”。
这个:
var hyperlink = foundText.getLinkUrl(0)
这只会获取在段落开头找到的超链接,例如,这意味着如果段落的第一个单词有超链接,这就是它return。在 getLinkUrl()
中,您应该使用搜索结果的起始索引。
解决方案
此代码将替换文本并保留超链接(如果有的话)。
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
// Getting info about result
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
// Modifying text
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
// Moving to next search result
searchResult = body.findText(textToReplace, searchResult);
}
}
它不会保留任何其他格式,因此您需要在代码的“获取信息”和“修改”部分添加一些行。
参考
更新
mshcruz 发现如果你用这样的参数调用函数:
replaceTextKeepHyperlink("Search", "PrefixedSearch")
该函数陷入了无限循环,因为它在刚刚替换的文本中找到了它要查找的文本,然后替换了那部分,如此循环往复。
他提供的修复程序包含在下面的 try 块中,以避免在文档末尾找到 textToReplace
时产生的错误:
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
try {
let rangeBuilder = DocumentApp.getActiveDocument().newRange();
rangeBuilder.addElement(searchResult.getElement(), start, end+ReplacementText.length - 1);
searchResult = rangeBuilder.getRangeElements()[0];
} catch (e){
Logger.log("End of Document")
return null
}
searchResult = body.findText(textToReplace, searchResult);
}
}
我需要在不影响超链接的情况下替换单词(必须为替换的单词保留超链接),那些没有超链接的替换必须以常规方式进行。
Here is the link of the coded Docs
我试过
function run() {
var findtext = "Search";
var replacetext = "Replacer";
var body = DocumentApp.getActiveDocument().getBody();
var foundElement = body.findText(findtext);
while (foundElement != null) {
var foundText = foundElement.getElement().asText();
var startOffset = foundElement.getStartOffset();
var endOffsetInclusive = foundElement.getEndOffsetInclusive();
var hyperlink = foundText.getLinkUrl(0);
foundText.insertText(0, findtext);
foundText.setLinkUrl(startOffset + findtext.length, endOffsetInclusive + findtext.length, hyperlink);
foundText.deleteText(startOffset + findtext.length, endOffsetInclusive + findtext.length)
foundElement = body.findText(findtext, foundElement);
}
}
主要问题是将 findText
的结果视为一个词。
这很棘手,因为您无法获得“单词”元素。你必须:
- 取整段元素即
findText
returns。这包含搜索结果。 - 获取找到的单词的开头和结尾的索引值。
- 获取该索引处的超链接
- 删除这些索引之间的文本
- 插入新文本,然后为超链接分配新索引。
例如:
foundText.insertText(0, findtext)
在结果所在元素的 start 处插入您要查找的文本,即“搜索”。
这个:
var hyperlink = foundText.getLinkUrl(0)
这只会获取在段落开头找到的超链接,例如,这意味着如果段落的第一个单词有超链接,这就是它return。在 getLinkUrl()
中,您应该使用搜索结果的起始索引。
解决方案
此代码将替换文本并保留超链接(如果有的话)。
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
// Getting info about result
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
// Modifying text
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
// Moving to next search result
searchResult = body.findText(textToReplace, searchResult);
}
}
它不会保留任何其他格式,因此您需要在代码的“获取信息”和“修改”部分添加一些行。
参考
更新
mshcruz 发现如果你用这样的参数调用函数:
replaceTextKeepHyperlink("Search", "PrefixedSearch")
该函数陷入了无限循环,因为它在刚刚替换的文本中找到了它要查找的文本,然后替换了那部分,如此循环往复。
他提供的修复程序包含在下面的 try 块中,以避免在文档末尾找到 textToReplace
时产生的错误:
function replaceTextKeepHyperlink(textToReplace, ReplacementText) {
var body = DocumentApp.getActiveDocument().getBody();
var searchResult = body.findText(textToReplace);
while (searchResult != null) {
var foundText = searchResult.getElement().asText();
var start = searchResult.getStartOffset();
var end = searchResult.getEndOffsetInclusive();
var hyperlink = searchResult.getElement().getLinkUrl(start);
foundText.deleteText(start, end)
foundText.insertText(start, ReplacementText)
foundText.setLinkUrl(start, start + ReplacementText.length - 1, hyperlink)
try {
let rangeBuilder = DocumentApp.getActiveDocument().newRange();
rangeBuilder.addElement(searchResult.getElement(), start, end+ReplacementText.length - 1);
searchResult = rangeBuilder.getRangeElements()[0];
} catch (e){
Logger.log("End of Document")
return null
}
searchResult = body.findText(textToReplace, searchResult);
}
}