Как разделить 1 длинный абзац на 2 более коротких? Документ Google - PullRequest
0 голосов
/ 04 марта 2020

Я хочу, чтобы абзацы содержали до трех предложений.

Для этого моя стратегия состоит в том, чтобы l oop во всех абзацах и найти окончание третьего предложения (см. Примечание). И затем, чтобы добавить символ "\ r" после него.

Вот мой код:

for (var i = 1; i < paragraphs.length; i++) {
  ...
  sentEnds = paragraphs[i].getText().match(/[a-zA-Z0-9_\u0590-\u05fe][.?!](\s|$)|[.?!][.?!](\s|$)/g);
  //this array is used to count sentences in Hebrew/English/digits that end with 1 or more of either ".","?" or "!"
  ...
  if ((sentEnds != null) && (sentEnds.length > 3)) {
    lineBreakAnchor = paragraphs[i].getText().match(/.{10}[.?!](\s)/g);
    paragraphs[i].replaceText(lineBreakAnchor[2],lineBreakAnchor[2] + "\r");
  }
}

Это отлично работает для первого раунда. Но если я снова запускаю код - текст после вставленного символа "\ r" не распознается как новый абзац . Следовательно, каждый раз при запуске скрипта будет вставляться больше «\ r» (новых строк).

Как заставить скрипт «понять», что «\ r» означает новый отдельный абзац?

ИЛИ

Есть ли другой персонаж / подход, который поможет?

Спасибо.

  • Примечание: я использую последние 10 символов предложения в предположении совпадения будут достаточно уникальными, чтобы сделать только 1 замену.

Ответы [ 2 ]

1 голос
/ 11 марта 2020

Без изменения собственного выражения регулярного выражения вы можете достичь этого.

enter image description here

Попробуйте этот подход разделить абзацы:

  • Получите все содержимое документа и создайте массив предложений.
  • Вставьте абзацы с максимум 3 предложениями после оригинальных абзацев.
  • Удалите оригинальные абзацы из ада.
function sentenceMe() {
  var doc = DocumentApp.getActiveDocument();
  var paragraphs = doc.getBody().getParagraphs();
  var sentences = [];
  // Split paragraphs into sentences
  for (var i = 0; i < paragraphs.length; i++) {
    var parText = paragraphs[i].getText();
    //Count sentences in Hebrew/English/digits that end with 1 or more of either ".","?" or "!"
    var sentEnds = parText.match(/[a-zA-Z0-9_\u0590-\u05fe][.?!](\s|$)|[.?!][.?!](\s|$)/g);
    if (sentEnds){
      for (var j=0; j< sentEnds.length; j++){
        var initIdx = 0;
        var sentence = parText.substring(initIdx,parText.indexOf(sentEnds[j])+3);
        var parInitIdx = initIdx;
        initIdx = parText.indexOf(sentEnds[j])+3;
        parText = parText.substring(initIdx - parInitIdx);
        sentences.push(sentence);
      }

    }
    // console.log(sentences);
  }

  inThrees(doc, paragraphs, sentences)
}

function inThrees(doc, paragraphs, sentences) {
  // define offset
  var offset = paragraphs.length;
  // Create paragraphs with up to 3 sentences
  var k=0;
  do {
    var parText = sentences.splice(0,3).join(' ');
    doc.getBody().insertParagraph(k + offset  , parText.concat('\n'));
    k++
  }
  while (sentences.length > 0)

    // Remove paragraphs from hell
    for (var i = 0; i < offset; i++){
      doc.getBody().removeChild(paragraphs[i]);
    }
}

Если вас интересует пользовательское меню, вот оно:

function onOpen() {
  var ui = DocumentApp.getUi();
  ui.createMenu('Custom Menu')
  .addItem("3's the magic number", 'sentenceMe')
  .addToUi();
}

Ссылки:

0 голосов
/ 04 марта 2020

На самом деле обнаружение предложений - непростая задача.

  • Предложение не всегда заканчивается точкой, знаком вопроса или восклицательным знаком. Если предложение заканчивается цитатой, то правила пунктуации в некоторых странах вынуждают вас поставить знак конца предложения внутри цитаты:

    Джон спросил: «Кто там?»

  • Не каждая точка означает конец предложения, обычно точка после заглавной буквы не заканчивает предложение, потому что это происходит после инициала. Предложение не заканчивается после J. здесь:

    Последний фильм Звездных войн ie был поставлен Дж.Дж. Абрамсом.

  • Однако иногда предложение заканчивается после заглавной буквы, за которой следует точка:

    Спонсором этого проекта является НАСА.

  • И сокращения могут сделать это очень трудно:

    Для получения дополнительной информации проверьте статью в Phys. Письма 66, 2697, 2013.

Имея в виду эти трудности, давайте все же попробуем получить какое-то выражение, которое будет работать в «обычных» случаях.

Сделать глобальное совпадение и подстановку. Сопоставьте

((?:[^.?!]+[.?!] +){3})

и замените его на

\1\r

Демо

Это ищет 3 предложения (предложение представляет собой последовательность не- точка, а не?, не!!, за которыми следуют точка, a? или a! и некоторые пробелы) и после них ставится символ \ r.

ОБНОВЛЕНО 2020-03-04

Попробуйте это:

var regex = new RegExp('((?:[a-zA-Z0-9_\\u0590-\\u05fe\\s]+[.?!]+\\s+){3})', 'gi');
for (var i = 1; i < paragraphs.length; i++) {
  paragraphs[i].replaceText(regex, '$1\\r');
}
...