Замена в регулярном выражении подстрок
Подскажите - как решаются подобные классы задач:
С помощью регулярного выражения в совпадающем фрагменте найти и заменить текст, соответствующий n-ной скобке. Например: в строке "1285423808063" в соответствии с регулярным выражением /[^3](8)(0)[6-8]/ заменить 8 на * и 0 на + чтобы получилось "128542380*+63" |
Rust,
var str = "1285423808063"; str = str.replace(/(380)(\d{2})/, "$1*+"); alert(str); |
Нужно общее решение. С частными всё понятно
|
Цитата:
|
Для понимания, нужно дописать
function(v,s) { return v.replace(s, function(f) { ... }); }так, чтобы при любой строке v и любом регулярном выражении s текст, соответствующий n-ной скобке обрамлялся тегами: <span class=Pn>$n</span> |
Цитата:
|
Rust,
возможно вы хотели так var str = "1285423808063"; function r(v,s,n) { return v.replace(s, function(f) { return --n ? f : '"'+f+'"' }); } str = r(str, /\d{2}/g,3); alert(str); |
строка:
Ну что сказать? -12.85 - это отрицательное число, а 0.86 - положительное регулярное выражение: /[^-\d.](\d+)(\.\d+)?/g Результат: Ну что сказать? -12.85 - это отрицательное число, а <span class=P1>0</span><span class=P2>.86</span> - положительное |
Повторяю. Строка и регулярка могут быть любой.
Обработку пишу я. Мне нужен общий метод. |
Цитата:
|
Не n-е совпадение шаблона, а n-я скобка!
Метод должен работать и без флага g |
Rust
плохо представляю что вам нужно. |
Цитата:
Регулярное выражение может содержать некоторое количество круглых скобок, обозначающих атомы регулярного выражения. В том числе и вложенные друг в друга! Функция должна найденные атомы регулярного выражения обрамлять указанными символами. |
Rust,
может кто-то другой сможет вам помочь, для меня, вашего описания по прежнему недостаточно. |
Может быть проблема в терминологии? Атом == группа вот в этом смысле
|
Rust,
Регулярка вообще любая? Может ли там быть, например, вот такая хрень: (\d)+ т.е. то что в скобках повторяется несколько раз и надо каждое повторение отдельно обработать? И может ли быть такое для вложенных скобок? Типа (...(\d)+...)* Сколько может быть скобок в регулярке? Это должно быть кроссбраузерно, или код только для Хрома и node.js? Я, кажется, понял, что надо, но задача крепкая, если в совсем общем виде. |
Цитата:
Цитата:
|
Цитата:
|
Цитата:
|
:) пока так вариант с неавтоматическим шаблоном...
var str = "Ну что сказать? -12.85 - это отрицательное число, а 0.86 - положительное"; function r(v,s) { return v.replace(s, function(...f) { return `${f[1]}<span class=P1>${f[2]}</span><span class=P2>${f[3]}</span>` }); } str = r(str, /([^-\d.])(\d+)(\.\d+)?/g); alert(str); |
Цитата:
|
Alexandroppolus,
Регулярка любая. Ограничений нет. Хрень может быть любая, в том числе и (...)+ Замен она влечёт ровно столько, сколько даёт match Вложенность групп тоже может быть: "1234567890" /\d(\d(\d)\d)\d/gрезульт ат: <span class=P0>1<span class=P1>2<span class=P2>3</span>4</span>5</span><span class=P0>6<span class=P1>7<span class=P2>8</span>9</span>0</span> да, совместимость со всеми браузерами очень желательна! |
Rust,
"1234" /(\d){2}/g <span class=P0><span class=P1>1</span><span class=P1>2</span></span><span class=P0><span class=P1>3</span><span class=P1>4</span></span> Так? |
Цитата:
let str = "Ну что сказать? -12.85 - это отрицательное число, а 0.86 - положительное"; function r(v,s) { return v.replace(s, function(...f) { return f.slice(1,-2).reduce((str, reg, i) => str.replace(reg, `<span class=P${++i}>$&</span>`), f[0]) }); } str = r(str, /[^-\d.](\d+)(\.\d+)?/g); alert(str); |
Цитата:
Цитата:
"aaabbbcc".match(/bb(b).(c)/)возвращает... Код:
{ "aaabbbcc".match(/bb(b).(c)/)возвращал... Код:
{ Так что, рони, ваш код из поста №24 работает неправильно... Вот с такими данными видно... let str = "aaaa"; function r(v,s) { return v.replace(s, function(...f) { return f.slice(1,-2).reduce((str, reg, i) => str.replace(reg, `<span class=P${++i}>$&</span>`), f[0]) }); } str = r(str, /aa(a)a/g); alert(str); |
Malleys,
спасибо! |
Размышления, для общего случая:
Придется вручную парсить регулярку, чтобы понять её структуру и при необходимости что-то в ней поменять. 1) Элементарный случай, линейная регулярка только из групп: /(...)(...)(...)/ - , оставляем как есть, замена по паттерну "<P1>$1</P1><P2>$2</P2><P3>$3</P3>" 2) Линейная регулярка с подстроками вне групп: /(...)...(...)/ - все необернутое оборачиваем в группы, получив /(...)(...)(...)/, замена по паттерну "<P1>$1</P1>$2<P2>$3</P2>", тут для $2 никаких тегов не добавлено, потому что это не было группой, а для $3 указаны теги P2, это была 2 группа изначально. Т.е. понадобится таблица соответствий, ибо номера групп сдвигаются. 3) Вложенные группы. /(...)(...(...)...(...)...)(...)/ - если нет ничего из п.4, то вторую группу можно просто растянуть в линейную по мотивам п.2: /(...)(...)(...)(...)(...)(...)(...)/, опять же с таблицей соответствий сдвинувшихся номеров. 4) Звездочки, плюсики, знаки вопроса, фигурные скобки. /...(regex)+.../ - делаем так: /(...)((?:regex)+)(...)/, в методе replace второй параметр - функция, и в ней матч для второй группы отдельно реплейсим регуляркой /regex/g, по тем же правилам, т.е. будет рекурсия. При составлении таблицы соответствий из п.2 не забыть про обратные ссылки в регулярке (\1, \2 и т.д.), их тоже поправить. Что делать с lookahead в п.4, пока не совсем понятно. |
Alexandroppolus, если вы рег. выр. из п. 3 /(...)(...(...)...(...)...)(...)/ преобразуете, как вы описали, то вы потеряете группу №2. Оно всё-таки должно стать так: /(...)((...)(...)(...)(...)(...))(...)/
Из п. 4 /...(regex)+.../ лучше так: /(...)(regex)+.../, ведь зачем вам группы, которые не используются. |
Цитата:
Цитата:
Если обобщить пп. 1-4, то суть вот в чем: мы всегда приводим регекс к виду из п.1 - последовательность групп, после каждой из которых нет + и прочего. Но если в этом регексе какая-то из групп содержит вложенные группы, то мы матч для неё обрабатываем по тем же правилам, как всю строку, иными словами, рекурсия. А п.4 - как тот же + загнать в линейную форму. Комплексный пример: регекс /a(b)c(d(e))(fg)+/ после преобразования получим 3 регекса: 1) Общий /(a)(b)(c)(de)((?:fg)+)/, где обертываем тегами группы 2 (с исходным номером 1, т.е. тег <P1>), 4 (тег <P2>). Вложенные группы расформировываем или нейтрализуем как ?:, они тут не нужны. 2) Матч 4 группы при этом обрабатываем регуляркой /d(e)/g, которая превратится в /(d)(e)/ и дальше рекурсия не пойдет. Здесь группа для (е) обертывается как <P3> 3) Матч 6 группы, обрабатываем регуляркой /(fg)/g, группа (fg) обертывается как <P4>, дальше рекурсия не пойдет. https://www.npmjs.com/package/regulex - парсилка |
Malleys, вы предельно ясно сформулировали мои потребности. Спасибо!
|
Часовой пояс GMT +3, время: 05:56. |