std-string-wc-replace | ![]() |
Replace all occurences in <str> matching <pattern> with <replacement>.
It expands the substring from left to right until it finds a match, incrementing the left position ine by one. So it finds minimal matches, not maximal, contrary to the normal regex behaviour.
Various options can be set to change the default behaviour.
While inserting the replacement into the input string, various special characters in the replacement string are expanded. $<, $> and $& are bound to the substrings before ("pre-match"), after ("post-match") and the exact found match.
Special replacements characters:
$<
pre-match
$&
match
$>
post-match
%<
delete to left
%
delete pre- or post-match
%>
delete to right
^
str: "L:/src/stdlib/STDSTR.lsp"
pattern: "/src*/"
$< <= "L:"
; pre-match
$& <= "/src/"
; match)
$> <= "stdlib/STDSTR.lsp"
; post-match
%<, %> and % delete a character, either in the pre-match, post-match or match.
% operations not at the start or end of the replacement strings are not special, they insert the "%" character. To insert a special character quote it by "`" (backtick), such as "`$&", "`$<" or "`$>"
=> $< "L"
; delete before (pre-match)=> $< "L"
; delete before (pre-match)=> $& "src/" $< "L:"
; delete after (match)=> $< "tdlib/STDSTR.lsp"
; delete before (post-match)=> $> "tdlib/STDSTR.lsp"
; delete after (post-match)=> $& "/src" $> "stdlib/STDSTR.lsp"
; deleteto left (match)=>
;delete nothingOptions:
e eval functions in replacement. The replacement can be string or a quoted function. If it is a string, all functions inside the string are expanded and the result is spliced together. But nested functions will return an invalid result.
i case insensitive search
cNUM count NUM, replace the first NUM matches only. Maximal 32767 replacements are done when no "c" argument is given.
x maximal matches rather than minimal. Search and replace the longest matching substring.
The implementation is very slow and limited, and uses the weird wcmatch syntax, which has much less features than a normal regular expression. In particular it supports no * and ? lists and no grouping by (), so we have no positional matches: $1, $2, ... and it is hard to find optional groups.
This simple syntax is familiar to wcmatch users, similar to shell globbing. Eventually we'll add a more powerful perl/sed/awk-style replacer.
Nested braces are not allowed in the replacement string yet!
For a workaround see the Capitalize example below.
i.e.: "(strcase (substr $& 1 1))(strcase (substr $& 2) t))"
will fail,
but '(cap $&)
or "(cap $&)"
will do.
(std-string-wc-replace "my House is yellow" "[aeiou]"
'(std-strcase $&) "c4")
=> "my HOUsE Is yellow"
;; add a "new" to the "src" dir
(std-string-wc-replace "L:/src/stdlib/STDSTR.lsp" "src*/"
"new$&" nil)
=> "L:/newsrc/stdlib/STDSTR.lsp"
;; search for a source dir and change the pathdelim
(std-string-wc-replace "L:/src/stdlib/STDSTR.lsp" "[/\\]src*[/\\]" "%>\\$&\\%<" nil)
=> "L:\\src\\stdlib/STDSTR.lsp"
;; fix all pathdelimiters
(std-string-wc-replace "L:/src/stdlib/STDSTR.lsp" "[/\\]" "\\" nil)
=> "L:\\src\\stdlib\\STDSTR.lsp"
;; Upcase from "L" till the next slash
(std-string-wc-replace "L:/src/stdlib/stdstr.lsp" "L*/"
'(strcase $&) "e")
=> "L:/SRC/stdlib/STDSTR.lsp"
;; Upcase from "L" till the last slash
(std-string-wc-replace "L:/src/stdlib/stdstr.lsp" "L*/"
'(strcase $&) "ex")
=> "L:/SRC/STDLIB/stdstr.lsp"
;; Capitalize
(defun cap (s)
(strcat (strcase (substr
s
1 1)) (strcase (substr
s 2) t)))
;; this pattern will miss the last word
(std-string-wc-replace "l:/src/stdlib/stdstr.lsp" "[A-Z]*[~A-Z]"
'(cap $&) "ei")
=> "L:/Src/Stdlib/Stdstr.lsp"
str: a string.
pattern: a string as wcmatch-style regular expression.
replacement: a string or quoted function. Several special characters are expanded.
options: a string or nil
A string.
On option "e" evaluated functions might produce sideeffects.
They can fail also. No exceptions are caught on expansion.
(std-require 'STDSTR)
Defined in STDSTR since v0.5005.