Home Download Buy Blog Forum Support

view.replace() regex

view.replace() regex

Postby jorbas on Mon Jan 28, 2013 6:19 pm

Is there a way to get view.replace() to use regex as it's replace? I have a plugin which will take multiple find and replace strings from a file and carry them out, view.find() will parse a regex string but view.replace() will just replace it literally, not taking into account things like "\1". I guess it doesn't work because the way it works is I'm selecting all the matches of the pattern and then replacing them with the replacement afterwards, even if it did parse regex it wouldn't know what "\1" referred to.
jorbas
 
Posts: 1
Joined: Mon Jan 28, 2013 6:12 pm

Re: view.replace() regex

Postby FichteFoll on Mon Jan 28, 2013 9:36 pm

Don't do this kind of text operation with sublime API, just get the text, modify it and then replace the old text. Basically, what you want is viewtopic.php?f=6&t=10610#p42057 and doing stuff to the text with re module inbetween.
FichteFoll
 
Posts: 388
Joined: Fri Mar 16, 2012 11:49 pm
Location: Germany

Re: view.replace() regex

Postby robertcollier4 on Tue May 21, 2013 8:13 am

Don't see why regex replace shouldn't be supported by the API.
robertcollier4
 
Posts: 154
Joined: Sun Feb 24, 2013 5:37 pm

Re: view.replace() regex

Postby bizoo on Tue May 21, 2013 8:45 am

view.replace() is not a "Find and replace" function, it just a replace a given subset of the view by a given string.
IMHO, what we need is a way to call the replace Command with our arguments.

I think you can do what you want with:
Code: Select all
View.find_all(pattern, <flags>, <format>, <extractions>)   [Region]
Returns all (non-overlapping) regions matching the regex pattern. The optional flags parameter may be sublime.LITERAL, sublime.IGNORECASE, or the two ORed together. If a format string is given, then all matches will be formatted with the formatted string and placed into the extractions list.


This method returns the position of your regexp (as View.find), but in addition you can give it a format and an empty list in the extractions argument.
After that you only have to loop through the lists and do the job (not tested):
Code: Select all
lstpos = view.find_all(pattern, <flags>, <format>, lstrepl)
for pos, repl in zip(lstpos, lstrepl):
  view.replace(edit, pos, repl)
bizoo
 
Posts: 879
Joined: Wed Dec 08, 2010 6:53 am
Location: Switzerland

Re: view.replace() regex

Postby sublimator on Tue May 21, 2013 1:32 pm

Remember, if you have a static list of regions, you should make modifications from the end of the buffer to the beginning, else you smash your offsets
It is better to remain silent and be thought a fool, than to speak out and remove all doubt
sublimator
 
Posts: 649
Joined: Thu Mar 20, 2008 5:41 am

Re: view.replace() regex

Postby bizoo on Tue May 21, 2013 1:40 pm

castles_made_of_sand wrote:Remember, if you have a static list of regions, you should make modifications from the end of the buffer to the beginning, else you smash your offsets

Oups, forget about this.

So something like:
Code: Select all
lstpos = view.find_all(pattern, <flags>, <format>, lstrepl)
for pos, repl in reversed(zip(lstpos, lstrepl)):
  view.replace(edit, pos, repl)
bizoo
 
Posts: 879
Joined: Wed Dec 08, 2010 6:53 am
Location: Switzerland

Re: view.replace() regex

Postby robertcollier4 on Wed May 22, 2013 1:54 pm

The find_all API (in ST3) is not finding the results for me that the regex find from the UI pane does.

The goal is to replace a file with many UNCs into local paths. So:
\\computer7\C$\testdir\test.bat
should get replaced into:
C:\testdir\test.bat

If I manually do a find-replace with regex in Sublime, it works:
Find: \\\\\S*\\([A-Z])\$
Replace With: \1:

However, if I try to find the regex string via the API, I get no results:
Code: Select all
import sublime, sublime_plugin
class PathUncToLocalCommand(sublime_plugin.TextCommand):
   def run(self, edit):
      RegionsResult = self.view.find_all("\\\\\S*\\([A-Z])\$", sublime.IGNORECASE)
      print(RegionsResult)

# This is the string to find via regex
# \\computer7\C$\testdir\test.bat


RegionsResult is an empty list and does not contain any results when trying to do the regex search via the API. However a match is found when doing the regex search manually from the find pane.
robertcollier4
 
Posts: 154
Joined: Sun Feb 24, 2013 5:37 pm

Re: view.replace() regex

Postby bizoo on Wed May 22, 2013 3:58 pm

Your code raise an exception in my ST2, not on your side ?

You must use a raw string (r"") for your regexp, or transform it in a correct Python string (double every \):
Code: Select all
RegionsResult = self.view.find_all(r"\\\\\S*\\([A-Z])\$", sublime.IGNORECASE)
bizoo
 
Posts: 879
Joined: Wed Dec 08, 2010 6:53 am
Location: Switzerland

Re: view.replace() regex

Postby facelessuser on Wed May 22, 2013 6:09 pm

I do this kind of stuff in my RegReplace plugin. I don't want to go into all the specifics right now, but you can check out the source if you want. You can create reg replace sequence commands with the RegReplace plugin, or you can dig around and see what I did.

ST2: https://github.com/facelessuser/RegReplace
ST3: https://github.com/facelessuser/RegReplace/tree/ST3

Anyways, maybe this will solve your issue, or help you solve your issue.
facelessuser
 
Posts: 1567
Joined: Tue Apr 05, 2011 7:38 pm

Re: view.replace() regex

Postby robertcollier4 on Wed May 22, 2013 6:26 pm

Thanks bizoo... adding the r"" to indicate raw string did the trick.

It is in fact possible to do regex-replace via sublime API with the "format string" and "extractions list". The following code works as an example of how to do a regex-replace from Sublime API.

Code: Select all
import sublime, sublime_plugin

class PathUncToLocalRegexReplaceExampleCommand(sublime_plugin.TextCommand):
   def run(self, edit):
      ListReplacements = []
      RegionsResult = self.view.find_all(r"\\\\(\S)*\\([A-Z])\$", sublime.IGNORECASE, "\\2:", ListReplacements)
      for i, thisregion in reversed(list(enumerate(RegionsResult))):
        self.view.replace(edit, thisregion, ListReplacements[i])


Above example successfully replaced:
\\computer7\C$\testdir\test.bat
into:
C:\testdir\test.bat
robertcollier4
 
Posts: 154
Joined: Sun Feb 24, 2013 5:37 pm

Next

Return to Plugin Development

Who is online

Users browsing this forum: Google [Bot] and 6 guests