使用正则表达式消除 google 应用脚本中的换行符

Eliminate newlines in google app script using regex

我正在尝试为 Google 文档编写一个附加组件的一部分,该附加组件使用 replaceText 消除了所选文本中的换行符。明显的 text.replaceText("\n",""); 给出了错误 Invalid argument: searchPatterntext.replaceText("\r",""); 我得到同样的错误。以下尝试无济于事:text.replaceText("/\n/","");text.replaceText("/\r/","");。我不知道为什么 Google App Script 不允许识别正则表达式中的换行符。

我知道已经有一个插件可以执行此操作,但我想将此功能合并到我的插件中。

即使使用基本

也会出现此错误
DocumentApp.getActiveDocument().getBody().textReplace("\n","");

我的全部功能:

function removeLineBreaks() {

var selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
    var elements = selection.getRangeElements();
    for (var i = 0; i < elements.length; i++) {
        var element = elements[i];

        // Only deal with text elements

        if (element.getElement().editAsText) {
            var text = element.getElement().editAsText();

            if (element.isPartial()) {
                text.replaceText("\n","");
            }

            // Deal with fully selected text
            else {
                text.replaceText("\n","");
            }
        }
    }
}

// No text selected
else {
    DocumentApp.getUi().alert('No text selected. Please select some text and try again.');
}

}

我现在通过多次试验和错误发现 - Wiktor Stribiżew 提供了一些急需的帮助(参见其他答案) - 有一个解决方案,但它依赖于 Google 脚本在正则表达式搜索中无法识别 \n\r 的事实。解决方法如下:

function removeLineBreaks() {
  var selection = DocumentApp.getActiveDocument()
    .getSelection();
  if (selection) {
    var elements = selection.getRangeElements();
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      // Only deal with text elements
      if (element.getElement()
        .editAsText) {
        var text = element.getElement()
          .editAsText();
        if (element.isPartial()) {
          var start = element.getStartOffset();
          var finish = element.getEndOffsetInclusive();
          var oldText = text.getText()
            .slice(start, finish);
          if (oldText.match(/\r/)) {
            var number = oldText.match(/\r/g)
              .length;
            for (var j = 0; j < number; j++) {
              var location = oldText.search(/\r/);
              text.deleteText(start + location, start + location);
              text.insertText(start + location, ' ');
              var oldText = oldText.replace(/\r/, ' ');
            }
          }
        }
        // Deal with fully selected text
        else {
          text.replaceText("\v+", " ");
        }
      }
    }
  }
  // No text selected
  else {
    DocumentApp.getUi()
      .alert('No text selected. Please select some text and try again.');
  }
}

说明

Google Docs 允许搜索与换行匹配的垂直制表符 (\v)。

部分文本是另一个问题。上面处理部分选定文本的解决方案通过从文本元素中提取文本字符串并在该字符串中搜索来找到换行符的位置。然后它使用这些位置来删除相关字符。重复此操作,直到达到所选文本中的换行数。

似乎在 replaceText 中删除使用 Shift-ENTER 输入的软 returns,您可以使用 \v:

.replaceText("\v+", "")

如果你想删除所有"other" control characters (C0, DEL and C1 control codes),你可以使用

.replaceText("\p{Cc}+", "")

请注意,\v 模式是 JavaScript 正则表达式引擎支持的结构,被认为匹配 垂直制表符 (≡ 3) 大多数 Google 产品中使用的 RE2 regex library

Google Apps 脚本函数 replaceText() 仍然不接受转义字符,但我可以通过使用 getText() 和通用 JavaScript replace() 来解决这个问题, 然后是 setText():

var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();

var bodyText = body.getText();

//DocumentApp.getUi().alert( "Does document contain \t? " + /\t/.test( bodyText ) ); // \n true, \r false, \t true

bodyText = bodyText.replace( /\n/g, "" );
bodyText = bodyText.replace( /\t/g, "" );

body.setText( bodyText );

这在文档中有效。不确定在 Sheet 中是否可以实现相同的功能(即使是,您可能也必须一次 运行 这个单元格)。

这是我的实用解决方案,用于消除 Google 文档中的换行符,或者更准确地说,是消除 Gmail message.getPlainBody() 中的换行符。 看起来 Google 使用“\r\n\r\n”作为普通 EOL,使用“\r\n”作为手动换行符 (Shift-Enter)。代码应该是自我解释的。 单独解决 Docs 中的换行问题可能会有所帮助。 一个解决方案可能不是很优雅,但很有魅力:-)

function GetEmails2Doc() { 
var doc = DocumentApp.getActiveDocument(); 
var body = doc.getBody(); 
var pc = 0;  // Paragraph Counter

var label = GmailApp.getUserLabelByName("_Send2Sheet"); 
var threads = label.getThreads(); 
var i = threads.length; 
// LOOP Messages within a THREAT  
for (i=threads.length-1; i>=0; i--) { 
for (var j = 0; j < messages.length; j++) { 
var message = messages[j]; 
/* Here I do some ...
body.insertParagraph(pc++, Utilities.formatDate(message.getDate(), "GMT",
"dd.MM.yyyy (HH:mm)")).setHeading(DocumentApp.ParagraphHeading.HEADING4) 
str = message.getFrom() + ' to: ' + message.getTo(); 
if (message.getCc().length >0) str = str + ", Cc: " + message.getCc(); 
if (message.getBcc().length >0) str = str + ", Bcc: " + message.getBcc(); 
body.insertParagraph(pc++,str);
*/ 
// Body !! 
var str = processBody(message.getPlainBody()).split("pEOL"); 
Logger.log(str.length + " EOLs"); 
for (var k=0; k<str.length; k++) body.insertParagraph(pc++,str[k]);
}
}
}

function processBody(tx) {

var s = tx.split(/\r\n\r\n/g);
// it looks like message.getPlainBody() [of mail] uses \r\n\r\n as EOL
// so, I first substitute the 'EOL's with the string pattern "pEOL"
// to be replaced with body.insertParagraph in the main function 
tx = ''; 
for (k=0; k<s.length; k++) tx = tx + s[k] + "pEOL"; 

// then replace all remaining simple \r\n with a blank 
s = tx.split(/\r\n/g); 
tx = ''; 
for (k=0; k<s.length; k++) tx = tx + s[k] + " ";

return tx;
}

Stack Overflow answer 删除,特别是“\n”。它可能有帮助,它确实帮助了我。