позиция подмасок в в регулярном выражении
пишу конструктор регулярных выражений, есть желание в нем сделать подсветку найденных групп в исходном тексте.
пример - исходный текст: 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 как таковыми и в этом вся сложность. Возможно вам поможет эта вещица. |
edison,
Сложение матчей не дает в результате исходную строку. Допустим, в регулярке есть вложенные скобки, или же скобки со звездой после. Что будет в этом случае? Ну, напр. строка "abcd1d2d3efg" и регулярка /(d\d)*/ |
Цитата:
|
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 |
Цитата:
во-вторых, c - позиция всего выражения, а не группы. |
Цитата:
Цитата:
Цитата:
|
Цитата:
Цитата:
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 |
Тут это сделано, код не обсфуцирован - бери да пользуйся.
|
Цитата:
^(.*?)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) и чем больше вложений тем больше подгрупп будет В общем изврат)) Возможно кому-то пригодится для дальнейших раздумий, но писать такой велосипед... |
Цитата:
alert( 'some text bla bla bla text la la la'.replace( /(t)(ext)/g, function( a, b, c ) { return b+ '#' + c + '#';}) ); или переписывать регу Цитата:
|
Цитата:
|
Цитата:
Я ток седня закончил составлять регулярку в многобукв. Вытаскивает из текста числа прописью и переводит их в числа: одиннадцать целых две сотых -> 11.02 |
Цитата:
|
Часовой пояс GMT +3, время: 20:46. |