Найти (заменить) последний пробел в любых заголовках HTML внутри блока HTML - PullRequest
2 голосов
/ 06 июня 2019

Я пытаюсь придумать какое-нибудь регулярное выражение, которое я могу использовать для замены последнего пробела неразрывным пробелом (управляющими вдовами) внутри заголовков только внутри блока HTML.

Пока чтоУ меня есть это:

const regex = /(<h.>.+?)\s+((\S|<[^>]+>)*)\n|$/gi
const replaced = text.replace(regex, '$1&nbsp;$2')

В regex101 похоже, что он работает правильно, но при запуске в JavaScript он добавляет дополнительный &nbsp в конец строки.

Пример блокаHTML может выглядеть следующим образом:

<h2>This is a test heading</h2>
<p>Here is some text</p>
<div>
  <h3>Here is a another heading</h3>
  <p>Some more paragraph text which shouldn't match</p>
</div>

Что следует заменить на:

<h2>This is a test&nbsp;heading</h2>
<p>Here is some text</p>
<div>
  <h3>Here is a another&nbsp;heading</h3>
  <p>Some more paragraph text which shouldn't match</p>
</div>

A ссылка на regex101 , показывающая рабочий шаблон.

Ниже приведен фрагмент, показывающий нерабочее поведение в JavaScript:

let text = "<h2>This is a test heading</h2>"
const regex = /(<h.>.+?)\s+((\S|<h.>)*)\n|$/gi
let replaced = text.replace(regex, '$1&nbsp;$2')
console.log(replaced);

text = `<h2>This is a test heading</h2>
<p>Here is some text</p>
<div>
  <h3>Here is a another heading</h3>
  <p>Some more paragraph text which shouldn't match</p>
  <p>Why is there a non breaking space at the very end?</p>
</div>`
replaced = text.replace(regex, '$1&nbsp;$2')
console.log(replaced);

Ответы [ 2 ]

0 голосов
/ 06 июня 2019

Здесь мы начнем с простого выражения, чтобы захватить нежелательный пробел, а также другие возможные пробелы, которые могут стоять перед последним словом, используя эту группу захвата (\s+):

<(h[1-6])>(.+)(\s+)([^\s]+)<\/\1>

Еслимы хотим добавить больше ограничений к нашему выражению, мы, безусловно, можем это сделать.

Демо

Тест

const regex = /<(h[1-6])>(.+)(\s+)([^\s]+)<\/\1>/gim;
const str = `<h2>This is a test heading</h2>
<p>Here is some text</p>
<div>
  <h3>Here is a another heading</h3>
  <p>Some more paragraph text which shouldn't match</p>
</div>
<h2>This is a test   heading</h2>
<p>Here is some text</p>
<div>
  <h3>Here is a another    heading</h3>
  <p>Some more paragraph text which shouldn't match</p>
</div>`;
const subst = `<$1>$2&nbsp;$4<\/$1>`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log(result);

RegEx

Если это выражение нежелательно и вы хотите изменить его, перейдите по этой ссылке на regex101.com .

RegEx Circuit

jex.im визуализирует регулярные выражения:

enter image description here

0 голосов
/ 06 июня 2019

Вы можете использовать

var regex = /(<(h\d+)>[^<]*?)\s+([^\s<]*?<\/\2>)/gi;

Заменить на '$1&nbsp;$3'.

Детали

  • (<(h\d+)>[^<]*?) - Группа 1 ($1): <, затем (h\d+) фиксирует в Группе 2 цифры * h и 1+, затем > и затем любые 0 или более символов других чем <, как можно меньше
  • \s+ - 1+ пробелов
  • ([^\s<]*?<\/\2>) - Группа 3 ($3): любые символы, кроме пробелов и <, насколько это возможно, а затем соответствующий закрывающий тег: </, то же значение, что и в группе 2 (\2 является обратная ссылка в шаблоне), а затем >.

JS демо:

var text = "<h2>This is a test heading</h2>\n<p>Here is some text</p>\n<div>\n  <h3>Here is a another heading</h3>\n  <p>Some more paragraph text which shouldn't match</p>\n</div>";
var regex = /(<(h\d+)>[^<]*?)\s+([^\s<]*?<\/\2>)/gi;
var replaced = text.replace(regex, '$1&nbsp;$3');
console.log(replaced);
...