[Question]
  [
In most programming languages, the string `Hello, World!` can be represented as `"Hello, World!"`. But if you want to represent `"Hello, World!"` you need to escape the double quotes with backslashes for `"\"Hello, World!\""`, and to represent *that* you also need to escape the backslashes resulting in `"\"\\\"Hello, World!\\\"\""`.
Your challenge is to, given a printable ASCII string that's been escaped multiple times (such as `"\"\\\"Hello, World!\\\"\""`, find how many characters it is when fully unescaped. Specifically, you should remove a single pair of enclosing `"` and replace `\\` with `\` and `\"` with `"`, until there are no more enclosing `"` left.
You can assume that the string will be syntactically valid - At all stages, as long as the string starts and ends with `"`, all other backslashes and double quotes will be properly escaped, and only `"` and `\` will be escaped. The input string will not be `"` at any level of escaping. If the string starts and ends with `"`, the last `"` cannot be escaped, so e.g. `"abc\"` won't occur.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest wins!
## Testcases
```
e -> 1
"hello" -> 5
"\"\\" -> 2
a""b"c -> 6
"c\d+e -> 6
"\"\\\"Hello, World!\\\"\"" -> 13
"c\\\"d\"" -> 5
"\"\"" -> 0
"r\"\"" -> 3
"\"hello\"+" -> 8
"\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"Hello\\\\\\\\\\\\\\\"\\\\\\\"\\\"\"" -> 5
"\\\\\"" -> 3
[""] -> 4
```
  
[Answer]
# [JavaScript (Node.js)](https://nodejs.org), 41 bytes
```
f=x=>/^".*"$/.test(x)?f(eval(x)):x.length
```
[Try it online!](https://tio.run/##XY3NTsMwEITvfoqwQordpk5LBapASW@IOwcuViXjbNIgExc7rcLTh9puqoq97My3P/MlT9Ip2x76RWcqHMe6GIoy3wGfwX3Oe3Q9Hdi2pniS@qzY88A1dk2/H18s/hxbizStXcq4RVm9thrffztFl1l67OtNwActFdJ8x2d0WySLMmH5d5MlriiV6ZzRyLVpaE0dY2xEv7AisEetDXjzSECAEEE/EAnwCcrrJwJKVHO8aL8j4M2fZcmHsbq680BAOFyt/fbZVxcQv0a9JGCvZu0HIV3APJDN9FzEmvpUMfQ/vOlwkxlYDPoD "JavaScript (Node.js) – Try It Online")
Trivial
[Answer]
# [Jelly](https://github.com/DennisMitchell/jellylanguage), 11 bytes
```
ŒV.ị=”"ȦƲ¿L
```
[Try It Online!](https://jht.hyper-neutrino.xyz/tio#WyIiLCLFklYu4buLPeKAnVwiyKbGssK/TCIsIuG7tMWT4bmj4oCcIC0+IOKAnSTigqzDhz1WfcmXL+KCrCIsIiIsWyJlIC0+IDFcblwiaGVsbG9cIiAtPiA1XG5cIlxcXCJcXFxcXCIgLT4gMlxuYVwiXCJiXCJjIC0+IDZcblwiY1xcZCtlIC0+IDZcblwiXFxcIlxcXFxcXFwiSGVsbG8sIFdvcmxkIVxcXFxcXFwiXFxcIlwiIC0+IDEzXG5cImNcXFxcXFxcImRcXFwiXCIgLT4gNVxuXCJcXFwiXFxcIlwiIC0+IDBcblwiclxcXCJcXFwiXCIgLT4gM1xuXCJcXFwiaGVsbG9cXFwiK1wiIC0+IDhcblwiXFxcIlxcXFxcXFwiXFxcXFxcXFxcXFxcXFxcIlxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFwiSGVsbG9cXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcIlxcXFxcXFxcXFxcXFxcXCJcXFxcXFxcIlxcXCJcIiAtPiA1XG5cIlxcXFxcXFxcXFxcIlwiIC0+IDNcbltcIlwiXSAtPiA0Il1d)
-2 bytes thanks to Jonathan Allan
## Explanation
```
ŒV.ị=”"ȦƲ¿L    Main Link
  ------Ʋ      Link Grouping (see below)
         ¿     While
  .ị               the first and last (index at 0.5)
       Ȧ           are all
    =”"            equal to "
ŒV             Evaluate (Python)
          L    Length
```
The footer runs all tests and prints `1` for any correct answers. `Ỵœṣ“ -> ”$€Ç=V}ɗ/€` means "split on newlines, split each string on substrings equal to `" -> "`, then for each pair, check that the result of the main link on the left side equals the right side evaluated (to convert to a number)".
For the link grouping, `Ʋ` combines four links into a monad, so you'd think we'd need to use `$` to capture the fifth, but since `”"Ȧ` would be an [LCC](https://jht.hyper-neutrino.xyz/beginners#leading-constant-chains) (a chain that begins with a nilad and only has monads and dyad-nilad/nilad-dyad pairs after it, so a chain with a constant result), it doesn't count that as a link and therefore keeps going one extra time. This is an important tip when understanding the link combining quicks as **all** of them do this and it is easy to miscount or misunderstand the grouping because it may be taking more links than you expect.
`ŒV.ị⁼⁾""Ʋ¿L` would also work where instead of `=”"Ȧ` to check that all are equal to `"`, we just check that it's equal to `['"', '"']`. This also makes the grouping a bit simpler because we don't have any potential LCCs so it just takes four links.
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 47 bytes
```
+`(?=.*"$)(^"(?!$)|\\(.)|(?!^)"$)(?<=^".*)
$2
.
```
[Try it online!](https://tio.run/##XYxBCsMgFET3nqIZLGgsLrpucNneoJuPJI1CC9KAdJm72xgVSmcz8x@fF/3n9Z7SUVzHpEZhBt2DS2EhTMflSiS0XLdtZcbmMljoXjJ@Zjolz/D0ISxgIBCBTcADM8NMTvkCCbf8cjrclxhclwEB@WVbbp@VxNpUpASFpqCS1i1F/Q9/ugr3E18 "Retina 0.8.2 – Try It Online") Link includes test cases. Explanation:
```
(?=.*"$)
```
Ensure the string ends with a `"` before making any replacements.
```
(^"(?!$)|\\(.)|(?!^)"$)
```
Replace a leading `"`, an escaped character or a trailing `"`, but not a lone `"`.
```
(?<=^".*)
```
Ensure that the string starts with a `"` before making any replacements.
```
$2
```
Unescape the character.
```
+`
```
Repeat until the string can't be unquoted further.
```
.
```
Get the length of the final string.
If `"` is excluded as being an unsupported input, then ten bytes can be saved by removing `(?!$)` and `(?!^)`.
[Answer]
# Excel ms365, 138 bytes
Assuming input in `A1`:
```
=LET(x,LAMBDA(f,s,IF(s<"",s,f(f,IFNA(SUBSTITUTE(SUBSTITUTE(MID(s,XMATCH("""*""",s,2)+1,LEN(s)-2),"\\","\"),"\""",""""),LEN(s))))),x(x,A1))
```
It's a recursive LAMBDA that will keep calling itself untill no more starting+leading double quotes.
---
# Google Spreadsheets, 107 bytes
Again, assuming input in `A1`, applying the same recursive logic with a few slight changes making use of the regex-functions:
```
=LET(x,LAMBDA(f,s,IF(REGEXMATCH(s,""".*"""),f(f,REGEXREPLACE(s,"^""|""$|\\(\\|"")","$1")),LEN(s))),x(x,A1))
```
[Answer]
# [Perl 5](https://www.perl.org/) `-pl`, 45 bytes
```
s/\\(\\|")/$1/g while s/^"(.*)"$/$1/;$_=y///c
```
[Try it online!](https://tio.run/##XY1Pi8JADMXv8ynGRw/@2TatbmVB1rMXzx6MitsOKgzb0i4sgp/dsZm2IuaSX17y8kpT2dTVpMNlNA6IFg0zD5lvGFGQ0En/ny/W6Jr2GEbjEQJRF8Hh@0pEmXOmcepE4WysLSBDqsBg9jxVR@AHmfBcIeN8YjqWG8ZKbB96U1Q2H4jA8MZkJtfNnHdC@7XlWKF6DjNZ@HTGxCtf/XNuq@99taHv4kvHS6bXuqAtsBP6vBfl36X4rV24TqM4iV1Y2gc "Perl 5 – Try It Online")
# [Perl 5](https://www.perl.org/) `-pl`, 54 bytes
Handles the `"\"foo\\\""` testcase I proposed in the comments. If that's not a valid test case, then the shorter version above will suffice.
```
s/\\(\\|")/$1/g while s/^"(.*[^\\])"$/$1/;say;$_=y///c
```
[Try it online!](https://tio.run/##XU1Na8JAEL3vr9g@cvArmaQ2Ugj23EvPPTgqNtmqsHRDIojQ395tZpMU6Vzmfcy8V5vG5r4lHb8ks4io6DDzhPkbU4oyOurr6WyNbmmHSTLb7Ji3U0RiFe3hVkT79Y2ISu9NF6EzhZOx1kFIrsBgDvhRHYAPlIJXCiVXczNguWG8yttCv7vGVg8iMMJjtpTrjleD0Kf2OFVo/shSjNDOmAfleQznfsY9Tl/6X7zbuOsM2lC0AbaCnqTg07lg/bj6cnZfrY/f8iTNUh/X9hc "Perl 5 – Try It Online")
[Answer]
# [Python](https://docs.python.org/3.12/), ~~51~~ 52 bytes
```
f=lambda s:f(eval(s))if'"'==s[-1:]==s[:1]else len(s)
```
Not complicated, but it works well.
**Explanation:**
Define a function f that takes an argument s:
```
f=lambda s:
```
If the string begins and ends with `"`, return the value of the function with backslashes evaluated:
```
f(eval(s))if'"'==s[-1:]==s[:1]
```
Otherwise, output the length of the string:
```
len(s)
```
[Try it online!](https://tio.run/##K6gsycjPM7YoKPr/P802JzE3KSVRodgqTSO1LDFHo1hTMzNNXUnd1rY4WtfQKhZEWxnGpuYUpyrkpOYB5f8XFGXmlWikaWTmFZSWaGhqav5XilGKiQHjGCQaBpQ8UnNy8tEFkWigdiUA "Python – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), ~~34~~ 33 bytes
```
Ｗ¬∨⌕θ"⌕⮌Φθλ"≔⪫⁻⪪✂θ¹±¹¦¹\\¦\¦\θＩＬθ
```
[Try it online!](https://tio.run/##XU5BCsIwELz7ipDTBuqh555EEBGtYq@9hLq0C0tik1ifH5NWoTiX2d2ZYbYbtOus5hjfAzEKqG2Aq4MDmQeMhZCtlKoQ83rHCZ3HpHFAl1VW6mtJEDvvqTdwsmTgQubloXkyBWiYOsz2shA19joglClXztkEuQwrGlW1uTkyAfbaBzij6cMAYyqpYkx9OdQu@PEP8ojM9v@44vxu3E78AQ "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
Ｗ¬∨⌕θ"⌕⮌Φθλ"
```
Repeat while the string starts with `"` and ends with a different `"`...
```
≔⪫⁻⪪✂θ¹±¹¦¹\\¦\¦\θ
```
... remove those `"`s, split the string on `\\`, remove any remaining `\`s, then join the string on `\`, thus unquoting the string.
```
ＩＬθ
```
Output the length of the final string.
(Yes I could use eval to save 14 bytes but that's boring.)
If `"` is excluded as being an unsupported input, then two bytes can be saved by replacing `Φθλ` with `θ`.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~91~~90 bytes
```
f=lambda s:f(s[1:-1].replace('\\"','"').replace(r'\\','\\'))if'"'==s[-1:]==s[0]else len(s)
```
because `eval` is evil :P, with inspiration from Jakav
[Try it online!](https://tio.run/##XYvBCkIhEEV/5TEbZ6AXSTvBff/wdGGlJEw@UVv09WZB8Wjg3gPnMvnZbms69h40u/v56qaqAtZFqlnaffGZ3cWjMAbEToCgnyrDDTWKKIYxaV2XWSr75sF6rn5in7BSzyWmhgFjyo@GRNTBgDGfmA2/ByfPvP7LDcc7vAA "Python 3 – Try It Online")
[Answer]
# [QBASIC](https://en.wikipedia.org/wiki/QBasic), 302 bytes
```
Q$ = CHR$(34): LINE INPUT T$: DO WHILE LEFT$(T$, 1) + RIGHT$(T$, 1) = Q$ + Q$: U$ = MID$(T$, 2, LEN(T$) - 2): T$ = "": C$ = "": FOR J = 1 TO LEN(U$): C$ = C$ + MID$(U$, J, 1): B = -(C$ <> "\"): T$ = T$ + RIGHT$(C$, B * ((INSTR("\\" + Q$, C$) > 0) + 2)): C$ = LEFT$(C$, 1 - B): NEXT: LOOP: PRINT LEN(T$)
```
A bit of nostalgia...
**Explanation:**
```
'Set quote mark because QBASIC doesn't have string escaping 
'then get string
Q$ = CHR$(34)
LINE INPUT T$
'Process the string while it starts and ends with quotes
DO WHILE LEFT$(T$, 1) + RIGHT$(T$, 1) = Q$ + Q$
    'Strip enclosing quotes, assign to a temporary variable,
    'prepare to rebuild the original string,
    'and prepare to track current character(s)
    U$ = MID$(T$, 2, LEN(T$) - 2)
    T$ = ""
    C$ = ""
    'Process string character by character.
    FOR J = 1 TO LEN(U$)
        'Add current character to current status
        C$ = C$ + MID$(U$, J, 1)
        'QBASIC boolean ops return -1 for true, 0 for false,
        'so set B to 0 if current character is an escape char, to 1 otherwise.
        B = -(C$ <> "\")
        'Add current character to string if not an escape char,
        'de-escaping if appropriate
        T$ = T$ + RIGHT$(C$, B * ((INSTR("\\" + Q$, C$) > 0) + 2))
       'Clear current character unless it's an escape char
        C$ = LEFT$(C$, 1 - B)
    NEXT
LOOP
PRINT LEN(T$)
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 10 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
Δ¬'"Qi.E]g
```
[Try it online](https://tio.run/##yy9OTMpM/f//3JRDa9SVAjP1XGPT//9XUlKKVlKKBVIA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9TVmmvpPCobZKCkn3l/3NTDq1RVwrM1HOtrU3/r/M/lUspIzUnJ1@JSylGKSZGiStRSSlJKZlLKTkmRTsVIhij5AFSoqMQnl@Uk6IIEohRUgIpAbJSwEyoSBGUjoEYGqOkrQQzIgYCYDQMQIxGF0SioQaCuUpc0UpKsVxKAA). (Note: in the single TIO, the input is wrapped within `"""`-quotes to always have a string input.)
**Explanation:**
```
Δ         # Loop until the result no longer changes:
 ¬        #  Push its first character (without popping the string)
  '"Qi   '#  If it's a double quote:
      .E  #   Evaluate the string as Elixir code
]         # Close both the if-statement and changes-loop
 g        # Pop and push the length of the reduced string
          # (which is output implicitly as result)
```
[Answer]
# [Pyth](https://github.com/isaacg1/pyth), 20 bytes
```
L?&b&qhbNqebNyvblbyw
```
[Try it online!](https://tio.run/##K6gsyfj/38deLUmtMCPJrzA1ya@yLCknqbL8/3@lGKWYGDCOQaJhQMkjNScnH10QiQZqVwIA "Pyth – Try It Online")
Same approach as Jakav's Python solution.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal/tree/version-2) `l`, 70 [bitsv2](https://github.com/Vyxal/Vyncode/blob/main/README.md), 8.75 bytes
```
Sλh\"=ßE;Ẋ
```
[Try it Online!](https://vyxal.pythonanywhere.com/?v=2&c=1#WyJsfj0iLCIiLCJTzrtoXFxcIj3Dn0U74bqKIiwiIiwiZS0+IDFcblwiaGVsbG9cIiAtPiA1XG5cIlxcXCJcXFxcXCIgLT4gMlxuYVwiXCJiXCJjLT4gNlxuXCJjXFxkK2UtPiA2XG5cIlxcXCJcXFxcXFxcIkhlbGxvLCBXb3JsZCFcXFxcXFxcIlxcXCJcIiAtPiAxM1xuXCJjXFxcXFxcXCJkXFxcIlwiIC0+IDVcblwiXFxcIlxcXCJcIiAtPiAwXG5cInJcXFwiXFxcIlwiIC0+IDNcblwiXFxcImhlbGxvXFxcIitcIiAtPiA4XG5cIlxcXCJcXFxcXFxcIlxcXFxcXFxcXFxcXFxcXCJcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcIkhlbGxvXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXCJcXFxcXFxcXFxcXFxcXFwiXFxcXFxcXCJcXFwiXCIgLT4gNVxuXCJcXFxcXFxcXFxcXCJcIiAtPiAzXG5bXCJcIl0gLT4gNCJd)
Bitstring:
```
0110001110110011010000001101101101100000011010011000101001000111010000
```
Port of 05ab1e except i had to add a "stringify" at the start for the final case
]