заменить и регулярное выражение исключение - PullRequest
0 голосов
/ 21 ноября 2018

Я хочу обернуть все слова текста в тег <trans>, чтобы иметь возможность работать с каждым словом.Наведите их, переведите на щелчок и т. Д.

Для этого мне нужно исключение в моей функции замены, чтобы игнорировать HTML-теги, такие как <br> или <span>.

Вот функция, которую я имею:

function wrapWords(str, tmpl) {
  return str.replace(/(?![<br>\<span class="gras">\</span>])[a-zA-ZÀ-ÿ]+/gi, tmpl || "<trans>$&</trans>");
}

Эта функция хорошо работает с русскими символами, но не с французскими.Проблема в том, что исключение <br> и <span> исключает французские символы b, r, s, p, a ... Из-за этого некоторые слова неправильно упакованы в мой тег <trans>.

Кто-нибудь знает, как можно исключить группу символов, таких как определенные теги <br>, например, не затрагивая буквы b и r на французском?

Спасибо за любой ответ!

Ответы [ 2 ]

0 голосов
/ 21 ноября 2018

При правильном использовании DOM это немного сложнее, но не о чем беспокоиться, так как это очень просто.

Вы хотите разделить текст, поэтому имеет смысл работать только с текстомузлы.Чтобы найти все текстовые узлы, мы могли бы оценить XPath или построить TreeWalker.

Как только мы узнаем, над какими узлами мы хотим работать, мы берем один узел за раз и получаем все пространствои последовательности без пробелов.Каждый будет преобразован в другой текстовый узел, но последовательности без пробелов будут дополнительно заключены в <span>.Мы добавляем их один за другим перед исходным узлом, что гарантирует правильный порядок, а затем, наконец, удалим исходный узел, когда все замещающие узлы будут на своем месте.

function getTextNodes(node) {
  let walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
  let textnodes = [];
  let textnode;
  while (textnode = walker.nextNode()) {
    textnodes.push(textnode);
  }
  return textnodes;
}
function wrap(element) {
  getTextNodes(element).forEach(node => {
    node.textContent.replace(/(\S+)|(\s+)/g, (match, word, space) => {
      let textnode = document.createTextNode(match);
      let newnode;
      if (word) {
        newnode = document.createElement('trans');
        newnode.appendChild(textnode);
      } else {
        newnode = textnode;
      }
      node.parentNode.insertBefore(newnode, node);
    });
    node.remove();
  });
}

wrap(document.getElementById('wrapthis'));
trans {
  background-color: pink;
}
Not affected<br/>

<div id="wrapthis">
  This is affected<br>
  <span class="gras">HTML tags are fine</span><br/>
  This as well<br/>
</div>

Not affected<br/>
0 голосов
/ 21 ноября 2018

Вот быстрый способ:

"foo bar baz".split(" ").map(w => "<trans>" + w + "</trans>").join(" ");

Объяснение:

предложение разделено пробелом, что дает Array.Каждый элемент этого Array затем оборачивается в <trans> теги.Затем все соединяется, чтобы создать обратно строку.

Редактировать : использование в DOM:

var sourceTextNode = document.createElement("div"); // here you're supposed to get an existing node...
sourceTextNode.textContent = "foo bar baz"; // ... and doing this is for the example purposes

sourceTextNode.innerHTML = sourceTextNode.textContent.split(" ").map(w => "<trans>" + w + "</trans>").join(" ");

sourceTextNode:

<div>
  <trans>foo</trans>
  <trans>bar</trans>
  <trans>baz</trans>
</div>

Примечание : Возможно, вы захотите исключить пустые элементы в разделенном массиве, которые вы получите, когда есть несколько последовательных пространственных символов.Один из способов сделать это - проверить непустоту элементов в фильтре:

sourceText.split(" ").filter(Boolean)...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...