* Help: f (repeat) modifier, and histsubstpattern + :s/l/r/ modifier escaping of [{()}]
@ 2023-08-16 18:32 Andy Kluger
2023-08-17 3:19 ` Bart Schaefer
0 siblings, 1 reply; 3+ messages in thread
From: Andy Kluger @ 2023-08-16 18:32 UTC (permalink / raw)
To: zsh-users
Hello!
For a small exercise I wanted to repeatedly remove empty pairs of
brackets/braces/parentheses from a string, and started with this
working solution:
s=$1 l=$#s
while (( 1 )) {
s=${s//(\{\}|\(\)|\[\])}
if [[ $#s < $l ]] { l=$#s } else { break }
}
print -r -- $s
But I remembered reading about the f (repeat) modifier, and thought
I'd try to remove the while loop.
setopt histsubstpattern
s='left[()]over'
print -rl -- ${s:fs/(\\{\\}|\\(\\)|\\[\\])//}
# printed: left[]over
# expected: leftover
I'm having two confusions:
1. Why do I need to double-backslash before each
brace/bracket/parenthesis, rather than single-backslash?
2. Why doesn't the replacement seem to happen to each subsequent
result of a former replacement?
Thanks for any help!
Andy
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Help: f (repeat) modifier, and histsubstpattern + :s/l/r/ modifier escaping of [{()}]
2023-08-16 18:32 Help: f (repeat) modifier, and histsubstpattern + :s/l/r/ modifier escaping of [{()}] Andy Kluger
@ 2023-08-17 3:19 ` Bart Schaefer
2023-08-17 23:09 ` Bart Schaefer
0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2023-08-17 3:19 UTC (permalink / raw)
To: Andy Kluger; +Cc: zsh-users
On Wed, Aug 16, 2023 at 11:33 AM Andy Kluger <andykluger@gmail.com> wrote:
>
> setopt histsubstpattern
> s='left[()]over'
> print -rl -- ${s:fs/(\\{\\}|\\(\\)|\\[\\])//}
> # printed: left[]over
> # expected: leftover
>
> I'm having two confusions:
>
> 1. Why do I need to double-backslash before each
> brace/bracket/parenthesis, rather than single-backslash?
Because the pattern is being passed through possible parameter
substitution before being passed through the pattern parser.
> 2. Why doesn't the replacement seem to happen to each subsequent
> result of a former replacement?
Because there's a bug. The pattern (and the replacement, though it's
empty in this case) are both rewritten in-place by at least one of
those two substitution passes, so the pattern isn't the same the
second time around and no longer matches.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Help: f (repeat) modifier, and histsubstpattern + :s/l/r/ modifier escaping of [{()}]
2023-08-17 3:19 ` Bart Schaefer
@ 2023-08-17 23:09 ` Bart Schaefer
0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2023-08-17 23:09 UTC (permalink / raw)
To: Andy Kluger; +Cc: zsh-users
On Wed, Aug 16, 2023 at 8:19 PM Bart Schaefer <schaefer@brasslantern.com> wrote:
>
> > 2. Why doesn't the replacement seem to happen to each subsequent
> > result of a former replacement?
>
> Because there's a bug.
Proof of bug / concept of fix. This might eat a lot of heap so
something more detailed is probably needed, so I'm not going to bother
to protect this from gmail line wrapping etc.
diff --git a/Src/subst.c b/Src/subst.c
index 14947ae36..7b866e638 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -4539,7 +4539,8 @@ modify(char **str, char **ptr, int inbrace)
case 'S':
hsubpatopt = (c == 'S');
if (hsubl && hsubr)
- subst(©, hsubl, hsubr, gbal, hsubpatopt);
+ subst(©, dupstring(hsubl), dupstring(hsubr),
+ gbal, hsubpatopt);
break;
case 'q':
copy = quotestring(copy, QT_BACKSLASH_SHOWNULL);
@@ -4627,7 +4628,8 @@ modify(char **str, char **ptr, int inbrace)
case 'S':
hsubpatopt = (c == 'S');
if (hsubl && hsubr)
- subst(str, hsubl, hsubr, gbal, hsubpatopt);
+ subst(str, dupstring(hsubl), dupstring(hsubr),
+ gbal, hsubpatopt);
break;
case 'q':
*str = quotestring(*str, QT_BACKSLASH);
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2023-08-17 23:10 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-16 18:32 Help: f (repeat) modifier, and histsubstpattern + :s/l/r/ modifier escaping of [{()}] Andy Kluger
2023-08-17 3:19 ` Bart Schaefer
2023-08-17 23:09 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).