regex - Use AutoHotkey to implement sed like replacement on clipboard

I want to use AutoHotkey to implement sed like replacement on the clipboard. I have tried several different ways to implement it, although I would like to make something which can be easily extended and be as functional as sed. Ideally it would take the act and take the same commands as sed and replace the current clipboard with the output. Since I use Ditto I will then have both the origlinal and output saved.

The solutions I have thought of and tested are to either make a hotstring which performs one specific sed replacement, e.g. using RegExreplace:

; Make text in clipboard "Camel Case" (retaining all spaces):
:*:xcamelsc::
    haystack := Clipboard
    needle := "\h*([a-zA-Zåäö])([a-zåäö]*)\h*" ; this retains new lines 
    replacement := "$U1$2 "
    result := RegExReplace(haystack, needle, replacement)
    Clipboard =
    Clipboard := result
    ClipWait
    sleep 100    
    send ^v 
return

Another example is

;replace multiple underscore with one space   
:*:xr_sc::
    haystack := Clipboard
    needle := "[\h]*[\_]+"
    replacement := " "
    result := RegExReplace(haystack, needle, replacement)
    Clipboard =
    Clipboard := result
    ClipWait
return

The flaw with this system is that I would have to make ~500 combinations of hotstrings for each possible combination I would like to have (e.g. a separate hotstring which to make all space underscore). I am not sure how to easily extend this.

Another way to do this is to use a GUI which previews the output and makes it possible to do more things, as implemented in clipboard replace. For this to be satisfactory I have made a hotstring which opens the GUI with the initial replacement filled in, and a hotkeys which automatically performs the replacement and pastes the output, etc. This system only requires that I specify the thing to replace, but I would rather have a system similar to the above which uses variables for all possible replacements so that I can refer to e.g. /^[\t]// to directly perform replacement.

A solution to do this would be to have a hotstring activate if I type "xr[a string of text to indicate what to replace][a string of text to indicate what to replace with]xx" i.e. "xx" would take the word just typed, parse it into the command, and perform it. This would mean that if I type "xr_sxx", the "s" part would be interpreted as two separate variables, and the "" would be assigned the needle and the "s" would be looked up in a table and then inserted in the replacement variable of the RegExReplace.

Does anyone know of a way to do this?

1 Answer

  1. Brent- Reply

    2019-11-14

    This system only requires that I specify the thing to replace, but I would rather have a system similar to the above which uses variables for all possible replacements so that I can refer to e.g. /^[\t]// to directly perform replacement.

    Does anyone know of an easy way to do this?

    Rather than specifying Hotstring for each scenario to perform a similar function I've used a method with a Hotkey, Input, and values stored in an Associative Array's.

    Here's an Example:

    data := {"xcamelsc": ["\h*([a-zA-Zåäö])([a-zåäö]*)\h*", "$U1$2 "]
               , "xr_sc": ["[\h]*[\_]+", " "]}
    
    f1::
        word := ""
        key := ""
        Loop {
            input, key, V L1 M T1, {Space}{Enter}{Tab}
            if (errorlevel == "EndKey:Space") {
                if (data.HasKey(word)) {
                    sendInput % "{BackSpace " StrLen(word)+1 "}"
                    haystack := Clipboard
                    needle := data[word].1
                    replacement := data[word].2
                    result := RegExReplace(haystack, needle, replacement)
                    Clipboard =
                    Clipboard := result
                    ClipWait
                    sleep 100    
                    send ^v 
                    }
                word := ""
                Break
            }
            else {
                word .= Format("{1:L}", key)
            }
        } 
    return
    
    ; Necessary for typing mistakes when using Input
    $BackSpace::
        word := SubStr(word, 1, -1)
        sendInput, {BackSpace}
    return 
    
    esc::exitapp
    

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>