Как проверить формат строки в Ruby, извлекая совпадения?

Этот ответ может быть немного запоздалым, но вы также можете использовать холст для масштабирования исходного изображения.

function handleDragStart(e) {
    var dragIcon = document.createElement('img');
    dragIcon.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC';
    var width = 100;
    var height = width * (3/4); // The height must be set explicitly. I'm assuming the image is 4:3 for this example
    var c = document.createElement("canvas");
    c.width = width;
    c.height = height;
    var ctx = c.getContext('2d');
    ctx.drawImage(dragIcon,0,0,width,height);
    dragIcon.src = c.toDataURL();
    e.dataTransfer.setDragImage(dragIcon, -10, -10);
}

http://jsfiddle.net/cnAhv/138/

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

3
задан Robin 15 February 2019 в 20:03
поделиться

2 ответа

def doit(str)
  r = /\A#{"(#\\d)\\s*"*str.count('#')}\z/      
  str.match(r)&.captures
end

doit "#1#2 #3 "    #=> ["#1", "#2", "#3"]
doit " #1#2 #3 "   #=> nil

Обратите внимание, что регулярные выражения зависят только от количества экземпляров символа '#' в строке. Поскольку в обоих примерах это число равно трем, соответствующие регулярные выражения равны, а именно:

/\A(#\d)\s*(#\d)\s*(#\d)\s*\z/

Это регулярное выражение было построено следующим образом.

str = "#1#2 #3 "
n = str.count('#')
  #=> 3
s = "(#\\d)\\s*"*n
  #=> "(#\\d)\\s*(#\\d)\\s*(#\\d)\\s*" 
/\A#{s}\z/ 
  #=> /\A(#\d)\s*(#\d)\s*(#\d)\s*\z/ 

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

Оператор безопасной навигации , & необходим в случае отсутствия совпадения (match возвращает nil).

Комментарий ОП относится к обобщению вопроса, в котором символ фунта ('#') является необязательным. Это можно решить, изменив регулярное выражение следующим образом.

def doit(str)
  r = /\A#{"(?:#?(\\d)(?=#|\\s+|\\z)\\s*)"*str.count('0123456789')}\z/
  str.match(r)&.captures
end

doit "1 2 #3 "     #=> ["1", "2", "3"] 
doit "1 2 #3 "     #=> ["1", "2", "3"] 
doit "1#2"         #=> ["1", "2"] 
doit " #1 2 #3 "   #=> nil   
doit "#1 2# 3 "    #=> nil 
doit " #1 23 #3 "  #=> nil 

Для строк, содержащих три цифры, регулярное выражение имеет вид:

/\A(?:#?(\d)(?=#|\s+|\z)\s*)(?:#?(\d)(?=#|\s+|\z)\s*)(?:#?(\d)(?=#|\s+|\z)\s*)\z/ 

[1120]

Хотя это верно что это регулярное выражение потенциально может быть довольно длинным, это не обязательно означает, что оно будет относительно неэффективным, так как предугадывание довольно локализовано.

0
ответ дан Cary Swoveland 15 February 2019 в 20:03
поделиться

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

s.scan(/(?:\G(?!\A)|\A(?=(?:#\d\s*)*\z))\s*\K#\d/)

См. Демонстрацию regex

Подробности

  • [ 112] - два варианта:
    • \G(?!\A) - конец предыдущего успешного совпадения
    • | - или
    • \A(?=(?:#\d\s*)*\z) - начало строки ([116 ]), за которым следуют 0 или более повторений # + цифра + 0+ пробелов и затем следует конец строки
  • \s* - 0+ пробелов
  • ]
  • \K - оператор сброса совпадений, отбрасывающий сопоставленный текст
  • #\d - символ #, а затем цифра

Короче: начало первой позиции строки соответствует, но только если строка справа (то есть вся строка) соответствует желаемому шаблону. Так как эта проверка выполняется с предварительным просмотром, индекс регулярного выражения остается там, где он был, и затем сопоставление происходит все время ТОЛЬКО после действительного совпадения благодаря оператору \G (он соответствует началу строки или концу предыдущего совпадения, поэтому (?!\A) используется для вычитания позиции начальной строки).

Демонстрация Ruby :

rx = /(?:\G(?!\A)|\A(?=(?:#\d\s*)*\z))\s*\K#\d/
p "#1 #2".scan(rx)
# => ["#1", "#2"]
p "#1 NO #2".scan(rx)
# => []
0
ответ дан Wiktor Stribiżew 15 February 2019 в 20:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: