Получить элемент пути из URL с помощью findText () - PullRequest
1 голос
/ 24 апреля 2020

Скажем, у вас есть следующий абзац в Google Do c, и вы хотите извлечь элемент из URL-адреса, относящегося к автомобилю.

У некоторого абзаца с некоторыми данными в нем есть URL http://example.com/ford/some/other/data.html. Есть и еще одна ссылка: http://example.com/ford/latest.html.

То, что я ищу, - это вытянуть «брод» из этого абзаца, чтобы я мог его использовать. И для простоты я знаю номер абзаца, я просто назову его «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 содержит весь текст абзаца.

Также есть ли способ захвата и использования данных из группы захвата, то есть содержимого в ()?

Ответы [ 2 ]

3 голосов
/ 25 апреля 2020

Я полагаю, что ваша цель, как показано ниже.

Как насчет этой модификации?

Точки модификации:

В вашем скрипте, когда 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. Пожалуйста, будьте осторожны.

Примечание:

  • Пожалуйста, используйте скрипт с включением V8.

Ссылка:

1 голос
/ 25 апреля 2020

В дополнение к ответу Танаике, этот ответ намеревается показать, что можно сделать, если бы вам пришлось использовать метод findText() (например, одновременное изменение атрибутов элемента, выделение совпадающих диапазонов и т. Д. c).


Проблема в том, что «данные» теперь весь абзац

Ну, это именно из-за предоставленных инструкций:

  1. Результат getElement() сам по себе Element.
  2. Результатом asText() на Element является Text экземпляр.
  3. Результат getText() на Text состоит в том, чтобы процитировать документы:

содержимое элемента в виде текстовой строки


есть ли способ захвата и использования данных

С findText() это кажется невозможным в соответствии с документами в то время слова, чтобы процитировать его для потомков:

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


Что делать?

Когда совпадение найдено, findText() возвращает экземпляр RangeElement, который имеет два интересующих метода: getStartOffset() и getEndOffsetInclusive(). Возвращаемые значения этих методов указывают на символ indexes текстового содержимого элемента. Таким образом, подобранная подстрока может быть извлечена с помощью метода 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]]
}

Примечания

  1. Любопытное наблюдение: видимо, для прохождения токены (\w, \s, et c) к выражению string, необходимо escape backsla sh (например, \\w будет проанализирован правильно).
  2. Обратите внимание, что приведенное выше решение возвращает string[][] для извлечения всех групп захвата ()
  3. Приведенный выше пример кода предназначен для среды выполнения V8.

Список литературы

  1. getElement() spe c
  2. asText() spe c
  3. getText() spe c
  4. findText() spe c
  5. getStartOffset() spe c
  6. getEndOffsetInclusive() spe c
  7. substring() документы на MDN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...