zsh-users
 help / color / mirror / code / Atom feed
* 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(&copy, hsubl, hsubr, gbal, hsubpatopt);
+                subst(&copy, 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).