On Sun, Aug 6, 2023 at 7:36 PM Bart Schaefer wrote: > > Circling back to this ... ... and again ... > With an increased understanding of lex.c gained by stepping through > variations of ${|...} a thousand times, I think I have identified two > possible ways to address this. Turns out there's a fundamental problem with ${var/pat/repl}, namely that upon reaching paramsubst() the only recognized quoting of the slash character is to precede it with a backslash. Conversely, gettokstr() recognizes '...', "...", and $'...' quoting, and may return STRING tokens containing backslashes that paramsubst() won't be able to deal with. Other things that have never worked are e.g. ${a/${b/c/d}/e}, which gives bad substitution, and ${a/"${b/c/d}"/e} which AFAICT always substitutes ${a} with no replacements, and ${a/"$( /bin/echo d )"/e} which is bad pattern: "$(. Fixing this properly would require doing a full-fledged parse inside paramsubst(), rather than just a search for unquoted backslashes. Several of my attempts so far have caused at least Test/Y01 to fail in comptesteval, so there is evidence for dependency on the existing behavior. > Something similar would have to be done with single quotes I had an idea here that seems to work: while reading single-quoted strings in gettokstr(), recognize when we're in a pattern and replace all / with \/. That only fixes '...' and $'...' at best, though. So, back to workers/51202, my original reply on this thread: handle double-quotes in paramsubst(), leaving single quotes to gettokstr(). This still isn't perfect (see above regarding ${a/${b/c/d}/e}) but it fixes the two Xfail tests in D04parameter and handles most of the straightforward cases, including a='/x/y/z' zsh -fc 'echo "${a/"/y/"/+}"' and even the ${a/"${b/c/d}"/e} example, although it'll break on any more double quotes inside other double quotes. Other existing tests still pass. Let me know what you think.