Параметризованные строки Javascript: заменить (RegExp, функция) неожиданное группирование / сопоставление

Регулярные выражения часто ускользают от меня. Я изо всех сил пытаюсь понять неожиданный результат с группировкой, и хотел бы, чтобы кто-то сказал мне:

  • Почему это не работает, как задумано
  • Как я мог достичь ожидаемого результата

Контекст:

Я работаю со строками, содержащими шестнадцатеричные цветовые коды. я использую replace() на этой строке, чтобы "подать" соответствующие цветовые коды в функцию, возвращающую HTML - вид параметризованной строки. Один из параметров в порядке, но другой соответствует всей строке?

Некоторый код:

Вот JSFiddle с простым примером (будьте осторожны: не принимает буквы до шестнадцатеричных кодов).

Код скрипки:

HTML:

<p>Please enter two hex color codes (digits only)</p>
<input id="colorsInput" type="text"></input>
<button id="booyah">Roll</button>
<p>Teh colorz</p>
<div id="colors"></div>
<p>Teh source</p>
<div id="html"></div>

JS:

$(document).ready(function() {

  function parameterizedHtml(p1, p2) {
    return '<div style="background-color:#' + p1 + '; width:50px; height:50px;">&nbsp;</div><div style="background-color:#' + p2 + '; width:50px; height:50px;">&nbsp;</div>'; 
  }    

  $('#booyah').click(function() {
    var colorsString = $('#colorsInput').val();
    var html = colorsString.replace(/(\d{6}).*(\d{6})/, parameterizedHtml);
    $('#html').text(html);
    $('#colors').html(html);
  });

});

Выход:

<div style="background-color:#548423 564212; width:50px; height:50px;">&nbsp;</div><div style="background-color:#548423; width:50px; height:50px;">&nbsp;</div>

Обратите внимание на первое background-color приписывать.

2 ответа

Решение

Первый аргумент replace дает функции обратного вызова общее совпадение. Затем следуют дополнительные аргументы для любых групп захвата. Так что если вы измените свою подпись функции на:

function parameterizedHtml(match, p1, p2)

... он начнет работать как положено.

Вот обновленная скрипка с изменением. Я также изменил регулярное выражение на /([a-f0-9]{6}).*([a-f0-9]{6})/i поэтому он принимает шестнадцатеричное значение, но учтите, что числовые значения цвета не обязательно должны быть длиной в шесть цифр. Они также могут быть трехзначными. #abc такой же как #aabbcc, Если вы хотите принять оба, то: /([a-f0-9]{3}|[a-f0-9]{6}).*([a-f0-9]{3}|[a-f0-9]{6})/i,

Итак, ваше регулярное выражение ищет цифры, а не шестнадцатеричные. Предполагая, что вы ищете два цветовых кода в одном входе, я бы пошел с

^([0-9a-FA-F], {6})[^0-9a-FA-F]*([0-9a-FA-F], {6})

При этом вы начинаете с 6 шестнадцатеричных символов, затем любого количества не шестнадцатеричных символов (включая ни одного), затем еще 6 шестнадцатеричных символов. Это также учитывает верхний и нижний регистр шестнадцатеричных альфа. И тогда скобка захватит первый цвет и второй цвет отдельно.

Другие вопросы по тегам