Сопоставить измененную версию первого совпадения только с одним выражением?
Я пишу кисть для Подсветки синтаксиса Алекса Горбачева, чтобы получить подсветку для кода Smalltalk. Теперь рассмотрим следующий код Smalltalk:
aCollection do: [ :each | each shout ]
Я хочу найти аргумент блока ": каждый", а затем сопоставлять "каждый" каждый раз, когда это происходит впоследствии (для простоты, скажем, каждое вхождение не только в скобках). Обратите внимание, что аргумент может иметь любое имя, например ": myArg".
Моя попытка сопоставить ": каждый":
\:([\d\w]+)
Это похоже на работу. Проблема для меня, чтобы соответствовать вхождениям "каждого". Я думал, что-то вроде этого может работать:
\:([\d\w]+)|\1
Но правая часть чередования кажется независимым выражением, поэтому обратная ссылка не работает.
Можно ли даже выполнить то, что я хочу, в одном выражении? Или мне придется использовать обратную ссылку во втором выражении (через другой вызов функции)?
2 ответа
Вы могли бы сделать это на языках, которые поддерживают просмотр переменной длины (AFAIK только языки платформы.NET, Perl 6 может). Там вы можете выделить слово, если оно соответствует (?<=:(\w+)\b.*)\1
, Но JavaScript вообще не поддерживает просмотр назад.
Но в любом случае это регулярное выражение будет очень неэффективным (я только что проверил простой пример в RegexBuddy, и механизму регулярного выражения требуется более 60 шагов, чтобы почти каждый символ в документе мог выбирать между соответствием и несоответствием), так что это не очень хорошая идея если вы хотите использовать его для подсветки кода.
Я бы порекомендовал вам использовать упомянутый вами двухэтапный подход: первый матч :(\w+)\b
(граница слова вставлена для безопасности, \d
подразумевается в \w
), затем выполните буквальный поиск результата поиска \1
,
Я считаю, что единственное, что хранится в движке Regex между матчами - это позиция последнего матча. Поэтому при поиске следующего совпадения вы не можете использовать обратную ссылку на совпадение ранее.
Так что нет, я не думаю, что это возможно.