Просмотр полной версии : позиция подмасок в в регулярном выражении
пишу конструктор регулярных выражений, есть желание в нем сделать подсветку найденных групп в исходном тексте.
пример - исходный текст:
xxab
aaaa
aaaa
bbbb
baxt
регулярка
/aaa(a)\na(a)aa\nbb(b)/
как найти позиции найденных групп?
чтобы я мог пометить их
xxab
aaaa
aaaa
bbbb
baxt
пример создан искусственно, регулярки могут быть разной сложности (любые) и исходный текст тоже.
В нэте полно online regexp тестеров. Посмотрите как оные устроены.
Смотрел несколько десятков онлайн конструкторов, не нашел чтобы подсвечивало подгруппы. Или всё совпадение подсвечивает или текстом выдает результат.
Нашел такое решение:
var m= /(s+)(.*?)(l)([^l]*?)(o+)/.exec('this is hello to you');
function indexOfGroup(match, n) {
var ix= match.index;
for (var i= 1; i<n; i++)
ix+= match[i].length;
return ix;
}
alert(indexOfGroup(m, 3));
но минус его в том, что придется добавлять в регулярку дополнительные группы, что будет очень большой геморой при сложной регулярке, ну и придется высчитывать позиции прежних матчей, а если группа в группе, так совсем не пойми что...
Пока думаю остановится на варианте с использованием ajax+php (preg_match PREG_OFFSET_CAPTURE) но постоянно отправлять на сервер запросы не есть гуд.
А никто не говорил, что будет легко.)
Я так понял у вас должна быть работа не с regexp js, а regexp как таковыми и в этом вся сложность. Возможно вам поможет эта (http://xregexp.com/) вещица.
edison,
Сложение матчей не дает в результате исходную строку. Допустим, в регулярке есть вложенные скобки, или же скобки со звездой после. Что будет в этом случае? Ну, напр. строка "abcd1d2d3efg" и регулярка /(d\d)*/
megaupload
02.04.2013, 12:25
пишу конструктор регулярных выражений
а зачем? (вопрос не риторический, если ты обучаешься то подскажу)
Aetae
Не нашел по ссылке решение задачи, только нашел поиск с опр позиции, а вот позиции подмасок не увидел. Еще там были примеры с index и lastIndex но это позиции вхождения всего шаблона.
rgl
Да я это написал, что если группа в группе, то будут сложности. Ну в теории можно вкладывать такие группы в другую группу, подсчитывать количество символов выкидывать ненужные значения и т.д. и т.п. в общем там кода будет на целый проект)
megaupload
Нет не обучаюсь, пишу под себя так как приходится много регехп составлять и необходим свой инструмент со своими нюансами в реализации от вставки текста из базы и подсчета количества символов, до автоматической замены некоторых участков в самой регулярке.
Остановлюсь тогда на связке ajax+php, спасибо что подумали со.
Хорошая программка, и группы подсвечивает (не онлайн)
http://www.regexbuddy.com/screens/debug.png
rgl Спасибо, но я наверное не в полной мере объяснил что именно хочу сделать.
конструктор уже написан, там нету только подсветки групп. Конструктор является небольшой частью всего функционала. Переносить весь функционал на другой яп будет очень проблематично, сейчас основаня часть это php+js из которого только JS на 500 кб (я говорю о всем функционале, а не только о конструкторе regexp). А так как я изучаю языки всего то около года. То я подумал, что возможно, где-то что-то упустил в мануалах и есть возможность выводить позиции матчей, например как это сделано в пхп. У меня сейчас только 3 выхода, это переписывать полностью клиенскую часть на С, найти возможность реализовать поиск позиции на JS или отправлять регехп в другую среду и получать оттуда уже ответ с позициями. В принципе не очень важная функция и сэкономит мне несколько секунд времени на составление 1 регехп, но из мелочей так и получается ощутимая экономия (до этого вообще приходилось вручную перебирать пару десятков регулярок и пробовать их обрезать, сейчас помогает конструктор и на автомате подставляет уже составленные регулярки и пробует их переделать под исходный текст). Пока пришел к выводу что для меня сейчас рациональнее сделать ajax+php потом попробую почитать мануалы по java,flash возможно там есть нужный мне функционал, чтобы сделать его на клиентской части, а не отправлять постоянно данные на сервер.
как найти позиции найденных групп?
alert( 'some text bla bla bla text la la la'.replace( /t(ext)/g, function( a, b ) { return '#' + b + '#';}) );
nerv_,
А где тут позиции?
(т.е. где число?)
А где тут позиции?
во-первых, нафига они нужны, если требуется
сделать подсветку найденных групп
во-вторых
function( a, b, c ) { // с - позиция a
во-первых, нафига они нужны,
во-вторых
function( a, b, c ) { // с - позиция a
Во-первых, как подсветить, не зная что нужно подсвечивать?
во-вторых, c - позиция всего выражения, а не группы.
как подсветить, не зная что нужно подсвечивать
первый пост почитай
сделать подсветку найденных групп в исходном тексте
c - позиция всего выражения, а не группы
о чем я написал постом выше
первый пост почитай
Читаю:
alert( 'some text bla bla bla text la la la'.replace( /t(ext)/g, function( a, b ) { return '#' + b + '#';}) );
и вижу, что получается не то. Ну, напр. сделаем так:
alert( 'CLEAR="left" causes the next text line to start down as soon as the left margin is clear'.replace( /next t(ext)/g, function( a, b ) { return '#' + b + '#';}) );
Получается не
CLEAR="left" causes the next t#ext# line to start down as soon as the left margin is clear
а
CLEAR="left" causes the #ext# line to start down as soon as the left margin is clear
Тут (http://www.gethifi.com/tools/regex) это сделано, код не обсфуцирован - бери да пользуйся.
бери да пользуйся.
Спасибо, но там выделяет не именно те матчи которые совпали, а идет реплейс
^(.*?)match1(.*?)match2(.*?)match3(.*?)$
на
$1<span class="group-1">match1</span>$2<span class="group-2">match2</span>$3<span class="group-3">match3</span>$4
соответственно это не точные позиции матчей.
Я примерно такое-же делал, только я сдвигал позицию под каждое совпадение, чтобы они были последовательно подсвечены.
Если ввести там регексп из моего первого сообщения то на выходе будет
xxab
aaaa
aaaa
bbbb
baxt
ну и группа в группе тоже сдвинет весь результат
(aaa(a))\na(a)aa\nbb(b)
xxab
aaaa
aaaa
bbbb
baxt
nerv_ заменяется ведь все вхождение регексп, вот если бы только подгруппы можно было заменить.
мысль только распарсить регулярку поочередно закрывая все группы (?:) кроме одной и по бокам этой группы заключать в скобки части регулярки.
допустим имеем
(aaa(a))\na(a)*aa\nbb(b)
преобразуем
(aaa(?:a))(\na(?:a)*aa\nbb(?:b)) т.к. первая группа начинается с самого вхождения, то выйдет всего 2 группы, тоже самое если мы работаем с последней группой и регексп заканчивается ей
получаем
aaaa
и
aaaa
bbbb
получаем начальную позицию длина pos=матч1+index
высчитываем позицию окончания
poslast=матч0-(матч1+матч3), тем самым мы высчитаем длину матча (a)* - когда группа повторяется или poslast=длинна совпадения+матч0-(матч1+матч2+матч3) в зависимости от того будем мы захватывать *?+ и т.д. после группы те. будет у нас так (a)* или мы преобразуем группу в ((?:a)*)
итого на выходе мы будем иметь позицию и длину вхождения
второе преобразование соответственно такое
(?:(aaa)(a))(\na(?:a)*aa\nbb(?:b))
((?:aaa(?:a))\na)(a)*(aa\nbb(?:b))
и т.д.
сложность в том, что нужно будет распаршивать регулярку по группам и закрывать группы. Кода возможно и не так много получится, но придется поломать голову над точным вычленением каждой подгруппы и позиций для образования новых подгрупп.
поправлюсь, количество новых групп не будет ограничено от 2 до 3, а будет расширятся если у нас подгруппа для которой мы находим позицию находится в другой подгруппе (-ах) т.е s(aaa(a)s)x - получится нужно проставить еще 4 подгруппы (s)(?:(aaa)(a)(s))(x) и чем больше вложений тем больше подгрупп будет
В общем изврат)) Возможно кому-то пригодится для дальнейших раздумий, но писать такой велосипед...
nerv_ заменяется ведь все вхождение регексп, вот если бы только подгруппы можно было заменить
alert( 'some text bla bla bla text la la la'.replace( /(t)(ext)/g, function( a, b, c ) { return b+ '#' + c + '#';}) );
или переписывать регу
и вижу, что получается не то
ну а додумать?) не? :)
ну а додумать?) не? :)
Внимательнее читаем, нэ. В предыдущем посте человек объяснил, почему это не так просто. Он имеет дело не с конкретной регуляркой, функция должна работать с произвольной.
функция должна работать с произвольной.
с чем бы она не работала, как правило, всегда есть от чего оттолкнуться. Если нет, то нет смысла писать код, тем более реги.
Я ток седня закончил составлять регулярку в многобукв. Вытаскивает из текста числа прописью и переводит их в числа: одиннадцать целых две сотых -> 11.02
с чем бы она не работала, как правило, всегда есть от чего оттолкнуться. Если нет, то нет смысла писать код, тем более реги.
Я ток седня закончил составлять регулярку в многобукв. Вытаскивает из текста числа прописью и переводит их в числа: одиннадцать целых две сотых -> 11.02
Это не особо сложно, а вот предусмотреть бесконечную вложенность в данном примере посложнее.)
vBulletin® v3.6.7, Copyright ©2000-2025, Jelsoft Enterprises Ltd. Перевод: zCarot