Сопоставить измененную версию первого совпадения только с одним выражением? - PullRequest
1 голос
/ 20 апреля 2010

Я пишу кисть для Подсветки синтаксиса Алекса Горбачева, чтобы подсветить код Smalltalk. Теперь рассмотрим следующий код Smalltalk:

aCollection do: [ :each | each shout ]

Я хочу найти аргумент блока «: каждый», а затем сопоставлять «каждый» каждый раз, когда это происходит впоследствии (для простоты, скажем, каждое вхождение, а не только в скобках). Обратите внимание, что аргумент может иметь любое имя, например ": MyArg"

.

Моя попытка сопоставить ": каждый":

\:([\d\w]+)

Кажется, это работает. Проблема для меня, чтобы соответствовать вхождениям "каждого". Я думал, что-то вроде этого может работать:

\:([\d\w]+)|\1

Но правая часть чередования выглядит как независимое выражение, поэтому обратная ссылка не работает.

Можно ли даже выполнить то, что я хочу, в одном выражении? Или мне нужно использовать обратную ссылку во втором выражении (через другой вызов функции)?

Ответы [ 2 ]

0 голосов
/ 20 апреля 2010

Я считаю, что единственное, что хранится в движке Regex между матчами, это позиция последнего матча. Поэтому при поиске следующего совпадения нельзя использовать обратную ссылку на совпадение до этого.

Итак, нет, я не думаю, что это возможно.

0 голосов
/ 20 апреля 2010

Вы могли бы делать это на языках, которые поддерживают просмотр переменной длины (AFAIK только в языках .NET Framework, Perl 6 может). Там вы можете выделить слово, если оно соответствует (?<=:(\w+)\b.*)\1. Но JavaScript вообще не поддерживает внешний вид.

Но в любом случае это регулярное выражение будет очень неэффективным (я только что проверил простой пример в RegexBuddy, и механизму регулярного выражения требуется более 60 шагов, чтобы почти каждый символ в документе мог выбирать между соответствием и несоответствием), так что это не хорошая идея, если вы хотите использовать его для подсветки кода.

Я бы порекомендовал вам использовать упомянутый вами двухэтапный подход: первое совпадение :(\w+)\b (для безопасности вставлена ​​граница слова, \d подразумевается в \w), затем выполнить буквальный поиск результата совпадения \1.

...