24.05.2019, 16:18
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от рони
|
пока так вариант с неавтоматическим шаблоном...
|
В твоем примере самый простой случай: регуляра состоит только из линейной последовательности групп (нет групп, вложенных одна в другую), после групп нет кванторов * и т.п., между группами нет ничего. Под такое дело шаблон легко составляется, его можно даже автоматически собрать.
|
|
24.05.2019, 16:44
|
|
Интересующийся
|
|
Регистрация: 24.05.2019
Сообщений: 10
|
|
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, 24.05.2019 в 16:58.
|
|
24.05.2019, 16:58
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
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>
Так?
|
|
24.05.2019, 17:15
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
Сообщение от Alexandroppolus
|
его можно даже автоматически собрать.
|
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);
|
|
24.05.2019, 17:25
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от рони
|
плохо представляю что вам нужно.
|
Сообщение от рони
|
чтобы это значило? подожду решения.
|
Смотрите, например код...
"aaabbbcc".match(/bb(b).(c)/)
возвращает...
Код:
|
{
"0": "bbbcc",
"1": "b",
"2": "c",
groups: undefined,
index: 3,
input: "aaabbbcc",
length: 3,
__proto__: Array.prototype
} |
а автору нужно, чтобы это было так... Чтобы...
"aaabbbcc".match(/bb(b).(c)/)
возвращал...
Код:
|
{
"0": "bbbcc",
"1": { valueOf() { return "b" }, index: 5 },
"2": { valueOf() { return "c" }, index: 7 },
groups: undefined,
index: 3,
input: "aaabbbcc",
length: 3,
__proto__: Array.prototype
} |
Тогда можно будет сказать, где в исходном тексте находится найденная группа
Так что, рони, ваш код из поста №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, 24.05.2019 в 17:32.
|
|
24.05.2019, 17:30
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,124
|
|
Malleys,
спасибо!
|
|
24.05.2019, 18:47
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Размышления, для общего случая:
Придется вручную парсить регулярку, чтобы понять её структуру и при необходимости что-то в ней поменять.
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, 24.05.2019 в 18:51.
|
|
24.05.2019, 19:33
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Alexandroppolus, если вы рег. выр. из п. 3 /(...)(...(...)...(...)...)(...)/ преобразуете, как вы описали, то вы потеряете группу №2. Оно всё-таки должно стать так: /(...)((...)(...)(...)(...)(...))(...)/
Из п. 4 /...(regex)+.../ лучше так: /(...)(regex)+.../, ведь зачем вам группы, которые не используются.
|
|
24.05.2019, 19:48
|
|
Профессор
|
|
Регистрация: 25.10.2016
Сообщений: 1,012
|
|
Сообщение от Malleys
|
Alexandroppolus, если вы рег. выр. из п. 3 /(...)(...(...)...(...)...)(...)/ преобразуете, как вы описали, то вы потеряете группу №2. Оно всё-таки должно стать так: /(...)((...)(...)(...)(...)(...))(...)/
|
Точно! Всё-таки придется п.3 рекурсивно обрабатывать.
Сообщение от Malleys
|
Из п. 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 - парсилка
Последний раз редактировалось Alexandroppolus, 24.05.2019 в 20:27.
|
|
27.05.2019, 09:48
|
|
Интересующийся
|
|
Регистрация: 24.05.2019
Сообщений: 10
|
|
Malleys, вы предельно ясно сформулировали мои потребности. Спасибо!
|
|
|
|