An example of this is a script to output the contents of .zsh_history
file in the manner of the history
command, so an emacs script would be invoked by a command line like display.sh.el < ~/.zsh_history_file
and would process it by reading the commands line by line rather than loading the whole file into a buffer, as the files could be very large.
Entries in .zsh_history
files are in the format
`: unixtime:duration;command`
: 1671297801:0;vim settings.php
: 1671298007:0;z private
: 1671298013:0;popd
: 1671298034:0;ll
: 1671298044:0;cd files/private/backup_migrate
and the history
command displays the excerpt above in the manner shown. It takes out the leading :
and the duration eg :0;
and outputs the right-aligned line number of the entry, the formatted unixtime and the command separated by two spaces.
1491 2022-12-17 17:23 vim settings.php
1492 2022-12-17 17:26 z private
1493 2022-12-17 17:26 popd
1494 2022-12-17 17:27 ll
1495 2022-12-17 17:27 cd files/private/backup_migrate
The interactive version which is noted at https://emacs.stackexchange.com/a/79254 works thus:
The search regexp is: \(: \)\([0-9]\{10\}\)\(:0;\)
which matches the :
, the unixtime
and the duration
noted above.
The replacement string is: \,(concat (format "%6d " (line-number-at-pos)) (rgx-get-time-string (match-string 2)) " "))
The reason why back references for \1
and \3
are not used in the replacement expression is because they are discarded, but in principle the function should take (match-string 0)
and (match-string 1)
and replace them with the empty string.
I tried replace-regexp-in-string
and failed, which prompted my earlier question, but it seems it may not be the most suitable function for this, and without examples the documentation has not proved helpful.
This question is about any other regex search and replace functions or combinations thereof which enable the use of the back references in the replacement function(s).
It may be that replace-regex-in-string
is the most appropriate one and I will just have to master it.
PS. I have managed a not quite correct version using replace-regexp-in-string
but will hold back from showing it to avoid muddying the waters further.
\(one\)\(two\)\(three\)
and then never doing anything with\1
and\3
, just don't group them. Matchone\(two\)three
instead, and only group the thing you're going to use.replace-regexp-in-string
specifically, but it made me realize that the non-interactive functions are not as straightforward as the interactive ones, and there is a whole lot of non-obvious surrounding state stored in variables with some accessible through functions. So I just want to know what more experienced users would have done in this case if I had asked them for a solution without mentioningreplace-regexp-in-string
or any other functions. The PS summarizes my ongoing experiences here, that is why I want something more general than specific.replace-regexp-in-string
, so I already answered there what you're asking here: You can (and I think should) use(when (string-match...) (setq var (replace-match...)))
using(match-string N)
to obtain the matched group for processing to establish your replacement.