0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|||||||||||
1 | |||||||||||
Подсветка синтаксиса05.11.2016, 20:16. Показов 3074. Ответов 21
Метки нет (Все метки)
Доброе время суток!
Задался целью сделать подсветку кода на javascript. В процессе столкнулся со сложностью регулярных выражений. Делаю один большой реплейс:
В строке "var self=this;" заключает все слова в спаны кроме this. И оно понятно... Сначала он видит ^var\s и заключает его в keyword-1, затем видит \sself= и заключает self в keyword-3, затем видит = его заключает в oper, а дальше он видит this; И тут ему, что бы понять что это слово, нужно увидеть какой-то символ до this и после него. После - без проблем ";" не буквенный символ, а вот перед this нет ничего, ни какого-то символа ни даже начала строки, поэтому он его и пропускает. Помогите, пожалуйста, разобраться в этой ситуации. Возможно как-то иначе стоит подойти к процессу подсветки синтаксиса, или как-то переосмыслить регулярку? Сразу я пробовал делать цепочку реплейсов, вроде:
0
|
05.11.2016, 20:16 | |
Ответы с готовыми решениями:
21
Подсветка синтаксиса в SHJS <textarea> и подсветка синтаксиса. подсветка в notepad++ Подсветка кода на js |
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
05.11.2016, 20:42 | 2 |
Сначала можно split-ом разбить строку с разделителем на кавычки, значения внутри кавычек(нечетные индексы получившегося массива) сохранить в отдельный массив, вместо них в текст добавить ~1~, ~2~ И т.д., провести все операции, а потом в самом конце все ~1~, ~2~ и т.д. заменить на сохраненные в отдельном массиве строки заключив в спаны с классом string.
1
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|
05.11.2016, 21:02 [ТС] | 3 |
Идея хороша, читал про такой способ. Меня смущает, что если в коде (в котором делаем подсветку) уже есть символы ~1~, ~2~... вся подсветка полетит. А ещё это решит вопрос со строками, но не проблему =this
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
06.11.2016, 00:47 | 4 |
0
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|
06.11.2016, 09:25 [ТС] | 5 |
= на предыдущем этапе заключилось в span.oper. Реплейс последовательно идёт по строке, видит "=", оно соответствует части регулярки ([\+\-\*\=\!]), значит заключает его в span. Дальше продолжает работу с оставшейся частью строки и видит сразу this без каких либо символов перед ним
В итоге 'var self=this;' => '<span class="keyword-1">var</span> <span class="keyword-3">self</span><span class="oper">=</span>this;'
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
06.11.2016, 10:11 | 6 |
quotes, А в каком месте вышего выражения определено, то перед ним должны быть какие-то символы? Просто поставьте в это место |^, что означает "или начало строки"
Добавлено через 3 минуты PS но вообще я проверил на онлайн-калькуляторе - ваше регулярное выражение находит "this;" даже если перед ним ничего не стоит, так что может дело в чем-то другом.
0
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
||||||
06.11.2016, 10:27 [ТС] | 7 | |||||
Но в строке 'var self=this;' this - не начало строки, а начало рассматриваемого отрезка. После того как регулярка разобралась с "=", она начинает рассматривать отрезок "this;". И первый символ который она видит это "t" (не начало строки, ни пробел, ни знак препинания), поэтому считает что это не начало слова.
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
06.11.2016, 10:35 | 8 |
quotes, Странное поведение функции, тогда либо найти все через match, потом заменять, либо несколькими регулярками, сначала найти идентификаторы, затем все остальное, что не идет впритык друг к другу.
0
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|
06.11.2016, 11:10 [ТС] | 9 |
Не совсем понимаю как это... Можно простенькие примеры этого?
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|||||||||||
06.11.2016, 11:31 | 10 | ||||||||||
quotes,
1) Я думаю, что все-таки ваш код должен работать, не может быть что нет такой возможности. Может надо поставить в регулярное выражение \b, типа граница слова или что-то такое. 2) Делайте все то же самое, просто в два захода. В первый возьмите из регулярного выражения только часть, касающуюся идентификаторов, ну и окружите проверкой, что перед и после нет числовых или буквенных символов, типа вот так:
3) Использовать метод exec для regExp, Он вернет все найденные вхождения, а вы уже будете думать что с ними делать
1
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
||||||||||||||||
06.11.2016, 15:18 [ТС] | 11 | |||||||||||||||
1) Да, если использовать \b то всё нормально. Вместо (^|[\s\!\@\#\$\%\^\&\*\)\(\-\+\=\[\{\]\}\'"\/\.\,\>\<\?\:\;\\]) пишу \b и всё здорово. Но \b не понимает букв кроме латинских, т.е. русские буквы он считает равносильными пробелу. Поэтому использовать его не могу.
2) на примере 'var self=this;'. Сначала:
Затем ищу, например, операторы (+-=/*):
3)Эта идея очень понравилась. Но грабли оказались те же
Может я что-то не то делаю внутри цикла? Может как-то иначе можно?
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
06.11.2016, 15:48 | 12 |
Сперва добавьте в начало каждого слова пробел. Здесь проблем возникнуть не должно, начало слова это всегда любой небуквенный знак перед любой буквой, русской или латинской. И потом уже запускайте свой код.
тут аналогичная идея, после каждой замены добавлять в исходную строку - str - пробел после найденного куска, тогда поиск каждый раз будет начинаться с пробела.
0
|
Почетный модератор
16844 / 6723 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
|
|
06.11.2016, 17:56 | 13 |
зачем вы каждый символ в регулярках экранируете? Это же ухудшает читабельность.
использовать заглядывания в духе (?=[a-z]) не пробовали? Ecmascript вроде поддерживает условные выражения в регулярках.
0
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|
06.11.2016, 18:33 [ТС] | 14 |
renat_dmitriev, получается в результате из 'var self=this;' я получу 'var self = this;' с подсветкой. Такой расклад не годится. Лишние пробелы не допустимы. Или я что-то не так понял?..
KOPOJI, да. Для пробела после слова можно использовать (?=....), а для пробела перед словом (?<=....), и всё будет работать идеально (на php проверял). Но в JS не работает конструкция (?<=....). Добавлено через 15 минут Может есть способ применять регулярки по-очереди, но исключать при этом из замены теги <span class="oper">?
0
|
392 / 294 / 121
Регистрация: 26.08.2016
Сообщений: 902
|
|
06.11.2016, 18:47 | 15 |
Так вы и заменяйте их вместе с пробелом. На самом деле абсолютно любой символ подойдет. Сначала этот символ вставляете перед каждым словом, потом ищете слова с этим символом вначале, и соответственно в вашей функции вы можете управлять заменой, взяв от pN подстроку со второй позиции.
Добавлено через 3 минуты Точнее не любой символ подойдет, а любой из тех, что вы не собираетесь подсвечивать.
1
|
Ренегат
|
|
06.11.2016, 23:06 | 16 |
Я вообще не понимаю кипиша, есть же highlight.js, на кой вообще свой велик изобретать?
0
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
||||||
07.11.2016, 10:38 [ТС] | 17 | |||||
BANO, для меня подсветка - не сама цель, а промежуточный этап. И этот этап мне нужно полностью контролировать, поэтому сторонние библиотеки мне не подходят (нужно хорошо осознавать, что куда). Я делаю редактор вроде brakets для web, и с подсветкой синтаксиса могут быть связаны какой-то api или что-то ещё.
renat_dmitriev, застрял на строках. Для "var self=this;" делаю превращение в "<var> <self>=<this>;", а потом границу слова отслеживаю по треугольным скобкам. Но если есть строки то получается бред при первой замене:
0
|
Почетный модератор
16844 / 6723 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
|
|||||||||||
07.11.2016, 10:59 | 18 | ||||||||||
Не по теме: BANO, ну захотелось видимо человеку изобрести свой велосипед - почему бы и нет :)
quotes, может лучше все-таки разбить на части, а не пытаться найти все разом? Ключевые слова вообще можно заменить все скопом, просто добавить проверку, что это не часть переменной и т.п. Навскидку, можно написать нечто подобное
чтобы избежать проблем с ключевым словом class, которое используется и в верстке, имхо, проще сделать дополнительную простую замену.. Но вы можете помучаться и так, если есть желание..
1
|
0 / 0 / 0
Регистрация: 05.11.2016
Сообщений: 10
|
|
07.11.2016, 11:12 [ТС] | 19 |
KOPOJI, ключевым словом может быть не только class но и другие например span где-то захочется подсветить. Но фиг с ним. Как после этого подсветить строки и, например, комментарии? Ведь теги '<span SPAN_CLASS="...">' тоже теперь участвуют в замене, и в них есть строки "...".
0
|
Почетный модератор
16844 / 6723 / 880
Регистрация: 12.06.2012
Сообщений: 19,967
|
|
07.11.2016, 11:19 | 20 |
Вот поэтому я и говорил про раздельный поиск и замену. Вам надо будет либо построчно искать и заменять, либо сохранять массив замен. Еще один вариант есть в фиксировании текущей строки замены - т.е., например, если строки с 10 по 20 - многострочный комментарий, то вы должны проверять, не находитесь ли вы сейчас внутри этого комментария? Ведь в этом случае замена не нужна. В общем, головоломка еще та у вас будет при парсинге путем регулярок
1
|
07.11.2016, 11:19 | |
07.11.2016, 11:19 | |
Помогаю со студенческими работами здесь
20
Подсветка синтаксиса на Си Подсветка синтаксиса Подсветка синтаксиса Подсветка синтаксиса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |