Search code examples
regexsublimetext

sublime text : use regular expression to find a number and do operations on the numbers captured for replace


I want to increment a number found in the text matching specific pattern. In extension, do any operation on it.

For example:

Mass in A flat D678 02.mp3
Mass in A flat D678 03.mp3
Mass in A flat D678 04.mp3

With the result:

Mass in A flat D678 03.mp3
Mass in A flat D678 04.mp3
Mass in A flat D678 05.mp3

I tried: (\d\d)\.mp3 to be replaced with $1+1.mp3 or {$1+1}.mp3


Solution

  • I really doubt that you can end up with some adequate regex (esp. because you may have number 99, which should become 100, 19 should become 20, etc.). You can write a plugin for this. To avoid most boilerplate and diving into plugins, layouts, etc., I'd suggest you to install PackageDev - it will care for proper files location.

    So, first install it: Ctrl+Shift+P, type "Package install", then Enter. In new dialog enter "PackageDev" and press Enter again. Wait for the plugin to download. (This requires Package Control to be installed)

    Now, open command palette again and type "PackageDev create" to select "PackageDev: Create Package". Type your desired package name in and press Enter. New window will open, with no files.

    Now, create your first plugin! Create new file and name it somehow. It must be a python file with .py extension. Add the following code:

    import sublime
    import sublime_plugin
    
    # Command name will be `testme` - CamelCase transforms to snake_case 
    # + `Command` suffix is removed.
    class TestmeCommand(sublime_plugin.TextCommand):
        def run(self, edit):
            dx = 0  # Track offsets if width has changed
            # Iterate over regions
            for p in self.view.find_all(r'\d\d\.'):
                p.a += dx
                p.b += dx
                orig = self.view.substr(p)  # Actual text
                # Replacement text
                # +- 1 here stand for "." length, you may need to tweak for other regexes
                replacement = str(int(orig[:2]) + 1).zfill(len(orig) - 1)
                dx += len(replacement) - len(orig) + 1
    
                self.view.replace(edit, p, replacement + '.')
    

    Save and go back to your file.

    Press Ctrl+` to open developer console, and write view.run_command('testme'), then press Enter.

    Basically that's all - however, if you need to use it regularly or in more convenient way, you can add a keyboard binding (PackageDev: New Keymap File) or command palette entry (PackageDev: New Commands File). I added command names in parentheses - use them from command palette in your plugin window, PluginDev will create a new file with pretty examples. Substitute "command" key with your command's name (testme in example above).

    (Side note: things would be much easier with short AWK one-liner, for example, you can transform everything without leaving your terminal and don't need to use Sublime Text for this)

    Resources: