LINUX.ORG.RU

Помогите сочинить регулярное выражение

 ,


0

1

Суть такова: должно быть срабатывание на любую подстроку не короче одного символа в пределах заданной. Короче говоря, есть строка, например target_link_libraries, нужно чтобы совпадало (match) target, _link_, link_lib, target_link и т.д. и не совпадало всякое прочее qwe, asd и т.д. То есть strstr(3) в общем-то.

Нужно для сниппетов в vim. Например, вот можно написать такой самодокументированный сниппет:

snippet 'target_link_libraries' "TARGET_LINK_LIBRARIES (<TARGET> PRIVATE|PUBLIC|INTERFACE <ITEM1> ... )" br
target_link_libraries(${1:<target>} ${2:PRIVATE} ${3:item1 ...})
endsnippet

Но я же не буду набивать полностью target_link_libraries, чтобы вставился сниппет. Обычно помнишь какую-нибудь подстроку только, например link или target. Хелп читал, на гугле ничего не нашлося.

★★★★★

Может лучше fuzzy match, чтобы `talili`, например, матчил? В автокомплитерах используется (deoplete, например).

NeXTSTEP ★★ ()

В чём проблема? Если не добавлять в регулярки символы ^ и $, то они так и будут работать.

> re:run("target_link_libraries", "link").
{match,[{7,4}]}
GoodRiddance ()
Ответ на: комментарий от GoodRiddance

Ну вот эта фиговина, которая сниппеты делает (UltiSnips) имеет следующий синтаксис:

snippet "trigger" "description" options
endsnippet

trigger это текст, по которому срабатывает сниппет. Он может быть регулярным выражением, если в options есть r. И вся эта балда работает на питоне. Например, '[Tt]arget_link_libraries', тогда этот сниппет будет вставляться по Target_link_libraries и target_link_libraries. А хотелось бы чтобы под любой подстроке срабатывало.

d_a ★★★★★ ()

Some people, when confronted with a problem, think «I know, I'll use regular expressions». Now they have two problems.

anonymous ()
Ответ на: комментарий от NeXTSTEP

А у меня UltiSnips, эта фигота вроде такое не умеет. Или набирать полностью trigger, и учить их все, либо регвыр.

d_a ★★★★★ ()

Ну то есть можно наверное устроить комбинаторный взрыв с реглярками вида (t|ta|tar|targ|targe|target|.....), но у меня всего 8ГБ ОЗУ.

d_a ★★★★★ ()

В общем, как strstr ничего не получилось, но можно прикостылить довольно похоже:

snippet '(add|exec(utable)?)' "ADD_EXECUTABLE (<NAME> SOURCE1 ...)" br
add_executable(${1:<name>} ${2:source1 source2 ...})
endsnippet

snippet '(target|link|lib|libraries)' "TARGET_LINK_LIBRARIES (<TARGET> <ITEM1> ... )" br
target_link_libraries(${1:<target>} ${2:item1 ...})
endsnippet

snippet '(target|link|lib|libraries)' "TARGET_LINK_LIBRARIES (<TARGET> PRIVATE|PUBLIC|INTERFACE <ITEM1> ... )" br
target_link_libraries(${1:<target>} ${2:PRIVATE} ${3:item1 ...})
endsnippet

http://i.imgur.com/RSgYk37.jpg

d_a ★★★★★ ()
Ответ на: комментарий от d_a

`t?a?r?g?e?t?_?l?i?n?k?_?l?i?b?r?a?r?i?e?s?` же. При помощи lookahead ещё минимальную длину можно установить

NeXTSTEP ★★ ()
Ответ на: комментарий от d_a

Нормальные вещи умеют в качестве аргументов функции жрать, внутри которой ты можешь городить что твоей анимешной душе угодно. Если нет, то какаха твой UltiSnips. Сам не юзаю для этого ничего.

r3lgar ★★★★★ ()
Ответ на: комментарий от NeXTSTEP

t?a?r?g?e?t?_?l?i?n?k?_?l?i?b?r?a?r?i?e?s?

В голосяндру!

Не, народ, вы меня смешите, чесслово. Функцией высрать регулярку перед скармливанием плагину не судьба, раз сам плагин не умеет жрать функции в качестве аргументов?

r3lgar ★★★★★ ()
Ответ на: комментарий от r3lgar

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

NeXTSTEP ★★ ()
Ответ на: комментарий от r3lgar

Если нет, то какаха твой UltiSnips.

Было бы лудше, дал бы! Других-то не завезли. SnipMate такое же точно, а японские поделочки (neosnippets et al) у меня вовсе не пашут, вот.

d_a ★★★★★ ()
Ответ на: комментарий от r3lgar

t?a?r?g?e?t?_?l?i?n?k?_?l?i?b?r?a?r?i?e?s?

Функцией высрать регулярку перед скармливанием

ректальная_тонзиллэктомия.djvu (2450 КБ)

Вообще, там есть (нашёл) триггер-мач по подстроке, но только c начала. А с середины не желает. Может, когда-нибудь сам допилякаю.

d_a ★★★★★ ()
Ответ на: комментарий от d_a

Кажется понял: сейчас каждый сниппет проверяет триггер по регулярке, а тебе нужно ровно наоборот: чтобы имена или дескрипшны сниппетов «грепались» по триггеру.

По-хорошему тут нужно код модифицировать, т.е. в ф-ции get_matching_snippets попробовать заменить

return [s for s in all_snippets if s.matches(trigger, visual_content)]

на

return [s for s in all_snippets if re.match(visual_content, s.description)]

или даже

return [s for s in all_snippets if re.match(visual_content, s.description) or s.matches(trigger, visual_content)]

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

GoodRiddance ()
Ответ на: комментарий от GoodRiddance

*сниппет проверяет введённую строку по триггеру, а тебе нужно ровно наоборот: чтобы триггеры или дескрипшны сниппетов «грепались» по введённой строке

GoodRiddance ()
Ответ на: комментарий от GoodRiddance

А, если в _snippet_dictionary.py прямо так поправить оно не работат! Вот жаль. Нет, специально пилить не надо, так неудобно же. Я пока на колясочке буду рассекать Помогите сочинить регулярное выражение (комментарий), оно вроде куда ни шло и триггеры зубрить не надо. А если плохо станет, к автору пойду челом бить, мне же нужно, и так все сразу пришли помогать http://i.imgur.com/74ca92i.gif

d_a ★★★★★ ()
Ответ на: комментарий от d_a

Too late:

From 510c2e4bdcab82933bd3f799a39028fbcefd8393 Mon Sep 17 00:00:00 2001
From: gr <gr@sportloto.com>
Date: Wed, 16 Nov 2016 02:40:00 +0000
Subject: [PATCH] Hm

---
 pythonx/UltiSnips/snippet/definition/_base.py           | 9 +++++++--
 pythonx/UltiSnips/snippet/source/_snippet_dictionary.py | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/pythonx/UltiSnips/snippet/definition/_base.py b/pythonx/UltiSnips/snippet/definition/_base.py
index b7f4bbe..15a71bf 100644
--- a/pythonx/UltiSnips/snippet/definition/_base.py
+++ b/pythonx/UltiSnips/snippet/definition/_base.py
@@ -241,7 +241,7 @@ class SnippetDefinition(object):
         """The matched context."""
         return self._context
 
-    def matches(self, before, visual_content=None):
+    def matches(self, before, meta = False, visual_content=None):
         """Returns True if this snippet matches 'before'."""
         # If user supplies both "w" and "i", it should perhaps be an
         # error, but if permitted it seems that "w" should take precedence
@@ -249,6 +249,12 @@ class SnippetDefinition(object):
         # boundary).
         self._matched = ''
 
+        if meta:
+            tokens = before.split()
+            if tokens != [] and re.search(tokens[-1], self._trigger):
+                self._matched = tokens[-1]
+                return True
+
         words = _words_for_line(self._trigger, before)
 
         if 'r' in self._opts:
@@ -291,7 +297,6 @@ class SnippetDefinition(object):
             self._context = self._context_match(visual_content)
             if not self.context:
                 match = False
-
         return match
 
     def could_match(self, before):
diff --git a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py
index d695902..2250ed4 100644
--- a/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py
+++ b/pythonx/UltiSnips/snippet/source/_snippet_dictionary.py
@@ -1,6 +1,5 @@
 #!/usr/bin/env python
 # encoding: utf-8
-
 """Implements a container for parsed snippets."""
 
 class SnippetDictionary(object):
@@ -36,6 +35,7 @@ class SnippetDictionary(object):
 
         if not potentially:
             return [s for s in all_snippets if s.matches(trigger,
+                                                         True,
                                                          visual_content)]
         else:
             return [s for s in all_snippets if s.could_match(trigger)]
-- 
2.7.3

GoodRiddance ()
Ответ на: комментарий от GoodRiddance

Спасибо огромное за ваш труд, такое заработало сразу, ровно так как и хотелось. Более того, я пока ваш вариант изучал, выдумал свой, несколько менее инвазивный:

diff --git a/pythonx/UltiSnips/snippet/definition/_base.py b/pythonx/UltiSnips/snippet/definition/_base.py
index b7f4bbe..2d1aa74 100644
--- a/pythonx/UltiSnips/snippet/definition/_base.py
+++ b/pythonx/UltiSnips/snippet/definition/_base.py
@@ -326,7 +326,7 @@ class SnippetDefinition(object):
             # therefore we check only for full-word trigger.
             match = self._trigger.startswith(words)
         else:
-            match = self._trigger.startswith(words)
+            match = self._trigger.count(words) > 0
 
         # By default, we match the words from the trigger
         if match and not self._matched:
diff --git a/pythonx/UltiSnips/snippet_manager.py b/pythonx/UltiSnips/snippet_manager.py
index e85bae4..ed29603 100644
--- a/pythonx/UltiSnips/snippet_manager.py
+++ b/pythonx/UltiSnips/snippet_manager.py
@@ -699,7 +699,7 @@ class SnippetManager(object):
     def _try_expand(self, autotrigger_only=False):
         """Try to expand a snippet in the current place."""
         before = _vim.buf.line_till_cursor
-        snippets = self._snips(before, False, autotrigger_only)
+        snippets = self._snips(before, True, autotrigger_only)
         if snippets:
             # prefer snippets with context if any
             snippets_with_context = [s for s in snippets if s.context]

То есть если документированные режимы (r, w, i) не заказаны, то будет делаться полнотекстовый поиск (_trigger.count(words) > 0). Хороший язык сделали пыхтонговский, можно даже вообще почти не зная пыхтонга поправить :)

d_a ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.