2013-09-09 4 views
4

Я уже некоторое время застрял на этом возвышенном сниппете.Regex для SublimeText Snippet

Я хочу отобразить правильное имя пакета при создании нового класса с использованием TM_FILEPATH и TM_FILENAME.

При печати TM_FILEPATH переменной, я получаю что-то вроде этого:

/Users/caubry/d/[...]/src/com/[...]/folder/MyClass.as

Я хотел бы превратить этот вывод, так что я мог бы получить что-то вроде:

com.[...].folder

Это включает в себя :

  • Снятие чего-либо до /com/[...]/folder/MyClass.as;
  • Извлечение TM_FILENAME с его расширением; в этом примере MyClass.as;
  • И, наконец, найти все косые черты и заменить их точками.

До сих пор, это то, что у меня есть:

${1:${TM_FILEPATH/.+(?:src\/)(.+)\.\w+/\l$1/}}

и это показывает:

com/[...]/folder/MyClass

Я понимаю, как заменить брызгами с точками, такими as:

${1:${TM_FILEPATH/\//./g/}}

Однако мне трудно добавить эту логику в предыдущую, а также удалить TM_FILENAME в конце логики.

Я действительно неопытный с Regex, спасибо заранее.

:]

EDIT:[...] показывает переменное количество папок.

+0

Действительно ли '[...]' в вашей строке, или вы говорите, что в вашей строке есть переменная сумма фактических папок? –

+0

Да, последнее :) – caubry

+0

Можете ли вы заверить, что файл всегда имеет расширение файла (и поэтому содержит период)? В этом случае я мог бы придумать уродливое, но работающее однорежимное решение. В противном случае это будет сложно. –

ответ

4

Мы можем сделать это в одной замене некоторыми обманами. Что мы сделаем, мы помещаем несколько разных случаев в наш шаблон и делаем другую замену для каждого из них. Трюк для этого заключается в том, что строка замены не должна содержать буквенных символов, но состоит исключительно из «обратных ссылок». В этом случае те группы, которые не участвовали в матче (потому что они были частью другого случая), просто будут записаны как пустая строка и не будут способствовать замене. Давайте начнем.

Во-первых, мы хотим, чтобы удалить все, вплоть до последней src/ (чтобы имитировать поведение вашего сниппета - использовать ungreedy квантора, если вы хотите, чтобы удалить все до первого src/):

^.+/src/ 

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

Теперь мы хотим сопоставить последующие папки до последнего. Мы будем записывать имя папки, также совпадать с конечным /, но напишем имя папки и .. Но я не сказал буквального текста в заменяющей строке! Таким образом, . должен исходить от захвата. Здесь возникает предположение, что ваш файл всегда имеет расширение. Мы можем получить период от имени файла с помощью lookahead. Мы также будем использовать этот предпросмотр, чтобы убедиться, что есть по крайней мере еще одна папка впереди:

^.+/src/|\G([^/]+)/(?=[^/]+/.*([.])) 

И мы заменим это с $1$2. Теперь, если первая альтернативная уловка, группы $1 и $2 будут пустыми, а ведущий бит все еще будет удален. Если вторая альтернатива ловит, то имя папки будет $1, а $2 захватит период. Милая. \G является якорем, который гарантирует, что все совпадения смежны друг с другом.

Наконец, мы возместим последнюю папку, и все, что следует за ним, и только записать обратно имя папки:

^.+/src/|\G([^/]+)/(?=[^/]+/.*([.]))|\G([^/]+)/[^/]+$ 

И теперь мы заменим это с $1$2$3 для окончательного решения. Demo.

Концептуально Подобный вариант был бы:

^.+/src/|\G([^/]+)/(?:(?=[^/]+/.*([.]))|[^/]+$) 

заменен $1$2. Я действительно только узаконил начало второй и третьей альтернативы. Demo.

Наконец, если Sublime использует Boost's extended format string syntax, это на самом деле можно получить символы в замене условно (без волшебно заклиная их от расширения файла):

^.+/src/|\G(/)?([^/]+)|\G/[^/]+$ 

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

(?1.:)$2 

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

+0

Благодарим вас за подробный ответ. Однако я до сих пор не понимаю, как обрабатывать информацию. При попытке: $ {TM_FILEPATH /.+/ src/| \ G ([^ /] +)/(? = [^ /] + /. * ([.])) | \ G ([^ /] +)/[^ /] + $} Я получаю только «src». Но при использовании демонстрационного теста я вижу, что выражение Regex должно отображать правильное значение. – caubry

+0

@caubry в моем ответе Я разместил все шаблоны без разделителей. Кажется, что в вашей среде вам нужны разделители (слэши), поэтому все слэши в шаблоне должны быть экранированы. И вам также нужно добавить заменяющую строку: '$ {TM_FILEPATH /.+\/ src \/| \ G ([^ \ /] +) \/(? = [^ \ /] + \ /.* ([ .])) | \ G ([^ \ /] +) \/[^ \ /] + $/$ 1 $ 2 $ 3} ' –

+1

При вводе вашего заданного значения вывод из этого фрагмента не отображается. Добавляя разделитель в конце Regex, я получаю: $ 2com /[...]/ folder/MyClass.as Еще раз спасибо, я пробовал разные отклонения, но я все еще не могу показать желание вывод. Это настолько запутанно: s Я понимаю это предложение лучше. «Известно, что регулярные выражения вредят чувствам людей». - http://bit.ly/HXC8WU -_- – caubry

Смежные вопросы