[Question]
  [
Python string parsing has quite a few edge cases. This is a string:
```
"a"
```
Putting 2 strings immediately after each other implicitly concatenates them, so this is also a string:
```
"a""a"
```
However, if you put 3 quotes in a row, it will create a "triple quoted string" which can only be ended by another 3 quotes in a row. A triple quoted string can contain other quotes. These quotes will not end the string unless there are 3 of them. Thus this is valid:
```
"""a"a"""
```
Of course, you can combine these together, so this is a valid string:
```
"""a""""a"
```
And this:
```
"""""aaa"""""""""
```
3 quotes in a row outside a string always starts a triple quoted string, even if such a string would be invalid. There is no backtracking.
A string is *not* valid if:
1. Any `a` appears outside of a string literal (would get `SyntaxError: invalid syntax` in python) OR
2. The end of the sequence is inside a string literal (would get `SyntaxError: unterminated string literal (detected at line 1)` in python)
## Your task
Given a string containing 2 distinct characters, one representing a double quote and another representing the letter "a" (most letters except b, u, r, and f would work exactly the same, you don't need to concern yourself with that detail), determine if it would be a valid python string, or invalid syntax.
You do not need to consider single quotes or how double and single quotes normally interact.
An array of booleans or an array of bytes would also be a valid input method. Thus some valid representations for `"a"` include `$2$`, `[0,1,0]`, or `[False, True, False]`.
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), shortest answer wins.
## Test Cases
| Truthy | Falsy |
| --- | --- |
| `"a"` (1-1) | `"a` (1) |
| `"a""a"` (1-2-1) | `"a"a"` (1-1-1) |
| `"""a"a"""` (3-1-3) | `""a"a"""` (2-1-3) |
| `"""a""""a"` (3-4-1) | `"""a"""a"` (3-3-1) |
| `"""""aaa"""""""""` (5-9) | `"""""aaa""""""""` (5-8) |
| `""""""""""""` (12) | `""""""aaa"""""""""` (6-8) |
| `"a""a""a""a"` (1-2-2-2-1) | `""""` (4) |
| `"a"""` (1-3) | `a` |
| `""` (2) | `"""a"` (3-1) |
| `""""""` (6) | `"""""""` (7) |
| `""""""""` (8) | `a""""""` (6) |
`eval` or `exec` or `ast.literal_eval` would be [valid](https://codegolf.meta.stackexchange.com/a/17718/91213) answers, though I hope to see more creative python answers as well.
  
[Answer]
# [Python](https://www.python.org), 57 bytes
```
lambda s:not re.sub(r'("""|"(?!"")).*?\1','',s)
import re
```
[Attempt This Online!](https://ato.pxeger.com/run?1=XZBLTsMwEIbFkpximE1mUBKRpPQRqequJ-iOsnBFIyKlsZW4CyRuwqYSgjvBaXD8iICsMt98-u3fb5_qRT_L7vJer_cfZ12ny69VK06HJwFD1UkN_TEbzgfqY0LEV6TNDSJzdrvZ53ESx8nAUXNSsh_NEFDLHlpoOpDq2NEdVxHski2soc0G1Taa-KGqiscIVN90mmracVLTltkFXL6vShQIlKc5wzUK88eRIR4WHgcnHbdoZzSkNKQchYkUljgHXUqZzlyKYw6VPsnMwpr2A7pPV079sxj50vsTyotg_suYW9d2-N2kCG2sNHOK3Y0VRGSvH-5pu4UTTeR0lBkW_vF-AA)
# [Python 3.11](https://www.python.org), 53 bytes
```
lambda s:not re.sub(r'("("")?+).*?\1','',s) 
import re
```
This [requires Python 3.11](https://docs.python.org/3.11/whatsnew/3.11.html#re) which that scandalously outdated ato does not support ;-P
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), ~~23~~ 22 bytes
```
^(?>("(?>""|)).*?\1)+$
```
[Try it online!](https://tio.run/##K0otycxL/K@q4Z7wP07D3k5DCUgoKdVoaupp2ccYamqr/P@vlKjEBcRgCkQCmVCWEkwQSCeCuWDApYQEoFphBkA1c6GpBEpwgY3mQrcBiwVQXRhWciVyIWkA8SE0AA "Retina 0.8.2 ‚Äì Try It Online") Link includes test cases. Explanation:
```
^
```
Match must start at the beginning of the string.
```
(?>...)+$
```
After each quoted segment is matched, it cannot be backtracked and reevaluated. Instead, further quoted segments must be matched until the end of the string is reached.
```
("(?>""|))
```
Three quotes must be matched if possible, otherwise one. This decision cannot be changed later.
```
.*?\1
```
Match the closing quote(s) as early as possible.
Edit: Saved 1 byte thanks to @Mukundan314.
[Answer]
# [C (GCC)](https://gcc.gnu.org), ~~132~~ ~~130~~ ~~109~~ 108 bytes
*-12 bytes thanks to [@ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)*
*-9 bytes thanks to [@jdt](https://codegolf.stackexchange.com/users/41374/jdt)*
*-1 bytes thanks to [@c--](https://codegolf.stackexchange.com/users/112488/c)*
```
#define T bcmp(s,"\"\"\"",n)
n;g(char*s){for(n=3;~n;n-=2)if(!T){for(s+=n;T**s;s++);return*s&&g(s+n);}n=!*s;}
```
[Try it online!](https://tio.run/##bU3LbsIwEDx7v2JxBbLzkCo4WvmL3KAH1yTGEmxRnIoDCp9e13ESCdGu5X3NzowprTEhvB2b1lGDNX6ay1X4gh/S4wVJIGWFOeku8/LefnWCqp16kKKy2krXilU9rX1ekaqzzCuf51J1Tf/dUeY3GxshkmqgahXBITjq8aIdCXkHNg6@7xzZ/fb9QwG7ndy5QWGb3osJkBLjIbvGvm8FXx8Rce3xQLxAu9wUs4qMEgzYAEPgmkP8qYw5tnPHl2WsOo0pgD/FTF0EZjK8XEYAkjS8OvxjMLP@WIKGJ8I4T/XHtGdtfShvvw "C (gcc) ‚Äì Try It Online")
Note: 3 bytes can be shaved by changing the quote char.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 25 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page) (no built-in); 2 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page) (built-in)
### Built-in
The two-byte built-in `≈íV` (evaluate Python code) works as a full program when given the raw input enclosed in `'''` - the exit code identifies the result: \$0\$ [if valid](https://tio.run/##y0rNyan8///opLD///@rq6srKSklAjGQBQA "Jelly ‚Äì Try It Online"), \$1\$ [if not](https://tio.run/##y0rNyan8///opLD///@rq6srKSklgjGQDQA "Jelly ‚Äì Try It Online").
Aside: The zero-byte program, when given the raw input, will actually give the evaluated string if valid, or the input if not. However, this does not conform with [decision-problem](/questions/tagged/decision-problem "show questions tagged 'decision-problem'") defaults.
### Non built-in
```
·∫†3∆§·∏¢·∏§‚Äò…ì·∫†‚Åπ∆§·∏¢√óT∆ä·∏ü·∏∂}+·∏¢
·∏ä√á¬°√êL
```
A monadic Link that accepts a list of \$1\$s (`"`s) and \$0\$s (`a`s) and yields an empty list (falsey) if valid or a non-empty list (truthy) if not.
**[Try it online!](https://tio.run/##y0rNyan8///hrgXGx5Y83LHo4Y4ljxpmnJwMFHjUuBMsdHh6yLGuhzvmP9yxrVYbyOd6uKPrcPuhhYcn@Pz//z/aUAcEDXTgdCwA "Jelly ‚Äì Try It Online")** Or see the [test-suite](https://tio.run/##y0rNyan8///hrgXGx5Y83LHo4Y4ljxpmnJwMFHjUuBMsdHh6yLGuhzvmP9yxrVYbyOd6uKPrcPuhhYcn@Px/uHvLoa22jxrmKhkYHm6318l61DBHwcZWASiiGfn/v7q6egyXUqISCIMpEAlkQllKMEEgnQjmggGXEhKAaoUZANXMhaYSKMEFNpoL3QYsFkB1YVjJlciFpAHEh9BAXwAA "Jelly ‚Äì Try It Online").
### How?
```
·∫†3∆§·∏¢·∏§‚Äò…ì·∫†‚Åπ∆§·∏¢√óT∆ä·∏ü·∏∂}+·∏¢ - Helper Link, prefix length that may be removed: list of 1s and 0s, L
 3∆§                 - for overlapping infixes of length 3:
·∫†                   -   all?
   ·∏¢                - head -> 1 if L starts with three 1s, 0 otherwise
    ·∏§               - double
     ‚Äò              - increment -> 3 if L starts with three 1s, 1 otherwise
      …ì             - new dyadic Link - f(L, Y=that)
        ‚Åπ∆§          - for overlapping infixes of length Y:
       ·∫†            -   all?
             ∆ä      - last three links as a monad - f(Z=that):
          ·∏¢         -   head (alters Z) and yield
            T       -   truthy indices (of the altered Z)
           √ó        -   multiply (vectorises)
               ·∏∂}   - lowered range (Y) -> [0] or [0,1,2])
              ·∏ü     - filter discard (these invalid locations)
                 +  - add Y (vectorises)
                  ·∏¢ - head (the empty list yields 0)
·∏ä√á¬°√êL - Main Link: list of 1s and 0s, L
   √êL - repeat while results are distinct applying:
  ¬°   -   repeat...
 √á    -   ...number of times: call the helper Link - f(current L)
·∏ä     -   ...action: dequeue
```
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 59 bytes
```
Ôº∑Œ∏‚âî‚éá‚åïŒ∏"""‚àß‚àß¬¨‚åïŒ∏"‚äñ‚ÑñŒ∏"‚úÇŒ∏‚äï¬ß‚åïÔº°Œ∏"¬πÔº¨Œ∏¬π‚àß‚äñ‚ÑñŒ∏"""‚úÇŒ∏‚Å∫‚Å∂‚åï‚úÇŒ∏¬≥Ôº¨Œ∏¬π"""Ôº¨Œ∏¬πŒ∏‚ÅºŒ∏œâ
```
[Try it online!](https://tio.run/##dU7LCsIwELz7FSGnBOpBBC89FR9QECnosZfSLm0gbsmjVr8@JlXbipglh53ZeZRNocu2kM71jZBAmOIkMUbUyC6gsdAPdhBYMRURmg9DeUQSj4R/au2cptxzOyg1XAEtVGzbdmgn0rNnKUoISIrTWWJTrOA@WCVSjoKIrILmCFjbxjcL@yv8X0j@aTHmZLIzbBORoeaIrn9c5@IvKgCKx4tMCx@zV10hTbDoOY@do@/nljf5BA "Charcoal ‚Äì Try It Online") Link is to verbose version of code. Outputs a Charcoal boolean, i.e. `-` for valid quotes, nothing if not. Explanation:
```
Ôº∑Œ∏
```
Repeat until the input becomes the empty string (because all quoted substrings were successfully parsed) or zero (because an error occurred).
```
‚âî‚éá‚åïŒ∏"""
```
If the input does not begin with `"""`, then...
```
‚àß‚àß¬¨‚åïŒ∏"‚äñ‚ÑñŒ∏"‚úÇŒ∏‚äï¬ß‚åïÔº°Œ∏"¬πÔº¨Œ∏¬π
```
... it must begin with `"` and contain at least two `"`, in which case slice it after the second `"`, otherwise...
```
‚àß‚äñ‚ÑñŒ∏"""‚úÇŒ∏‚Å∫‚Å∂‚åï‚úÇŒ∏¬≥Ôº¨Œ∏¬π"""Ôº¨Œ∏¬πŒ∏
```
... it must begin contain at leat two `"""`, in which case slice it after the second `"""`.
```
‚ÅºŒ∏œâ
```
Output whether the input was valid.
[Answer]
# Regex (Javascript/PCRE), ~~31~~ 28 bytes
* -3 bytes thanks to Neil and Mukundan314
```
^(""$|"a+"|"""("?"?a)*""")+$
```
[Try it on regexr](https://regexr.com/7199l)
Basically:
* Empty single-quoted string may appear only at the end
* A single-quoted string outside the end must contain at least one element, this makes it unambiguous with a triple quoted string. Since "stock" regex has no way to prevent backtracking there must be no ambiguity.
* A triple quoted string may contain up to 2 quotes in a row. These quotes may not be at the end. If they where at the end they would end the string early. Unlike single quoted strings tripple quoted ones may be empty without introducing ambiguity.
[Answer]
# x86-64 machine code, 24 bytes
```
E2 03 6A 06 59 B0 14 AE 7B F6 18 D2 D2 C0 24 01 83 C9 03 00 D0 78 EE C3
```
[Try it online!](https://tio.run/##ZVJNb9swDD2Lv4JTEUBq0yHpRw5xvUvPvfQ0oOnBkeRYhSM5ltMpKPrX59FqHDSYYIiP71GPJGB1vVGq74uwRYHPXMBuyWrvG3RQLlmzDxUuMmyIaFUEt2Rb/45FPcVZnN8BC6oIa2BvjccdZes1atJ0Daz1dapThAunE54D8y0aFad4S6z@Yofqt0ANWWs6kBxlBqoqWiyF8i50mJLLIDN891bjTlABXFin6r02@BA6bf3P6tcZ1Vq3GTiwrsNtYZ2Q8AEsWYWXm/vFawbsT2Vrg4KWcKXgk8CnGCTmOc4lMNaQRzfwdtVNwsqRWooghxp6O6or91SoyjqDymuz5IM29IyY42yKB0q1x4@xHCezm9/kdMiF2LtgN87otOCl3MmXeHX1KrNPPA52wB9kEh9vvzdEMbG4PnQmyDRTJPGz73nkwCN9/Aulm6fIB3QCKZ7UEVGMSUjnPwb4t3NMzh@kvmP3keFAEx07wbnTyRGOLvBXlXWxCf31dnFHF/2SOW1s6n8 "C (gcc) ‚Äì Try It Online")
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes the address of a null-terminated byte string consisting of `"` and `x` in RDI, and returns 0 or 1 in AL. The starting point is after the first 2 bytes.
---
This uses a single-pass algorithm: it processes each character of the string in order. The validity condition can be checked by a [DFA](https://en.wikipedia.org/wiki/Deterministic_finite_automaton) like this:
[![An incomplete DFA, with seven states S, N0, N1, N2, T0, T1, and T2, connected by quote transitions in that order. There is also a quote transition from T2 to N0, and x transitions from S and N1 to S and from T0, T1, and T2 to T0. The start state is N0. States N0 and N2 are accepting.](https://i.stack.imgur.com/RsUnx.png)](https://i.stack.imgur.com/RsUnx.png)
(Technically, to satisfy the most common definition of a DFA, we would need to fill in the missing transitions, pointing them to a sink state. But the program can easily return before the end of the string, so this is not a problem.)
We number the states 7, 6, 5, 4, 3, 2, 1 in the order shown, so that implementing the `"` transition is easy: subtract 1, and if the result is 0, change it to 6. The current state number is held in RCX.
The `x` character and the null terminator can be handled together, as follows:
|  | N0/N2 | Other |
| --- | --- | --- |
| NUL | Success | Failure |
| `x` | Failure | S/T |
The "S/T" case is implemented by bitwise-ORing the state number with 3, which changes it to 3 or 7 as appropriate.
In assembly:
```
q:  loop n          # (For ") Decrease RCX by 1, and jump if the result is not 0.
f:  push 6; pop rcx # (When it hits 0, or at the start) Set RCX to 6.
n:  mov al, 0x14    # Set AL to 0x14.
    scasb           # Read a byte from the string, advancing the pointer,
                    #  and set flags based on AL minus that byte.
    jpo q           # Jump if the sum of the bits is odd (true only for ").
    sbb dl, dl  # Subtract DL+CF from DL, making it 0 for NUL or -1 for x.
    rol al, cl  # Rotate AL left by the low byte of RCX, the state number...
    and al, 1   # ...and keep only the low bit, which is 1 only for state 4 or 6.
    or ecx, 3   # Bitwise-OR ECX with 3, changing 1‚Äì3 to 3 and 4‚Äì7 to 7.
    add al, dl  # Add DL to AL, making 1 for success, 0 for failure, -1 for S/T.
    js n        # Jump (to continue processing the string) if it's negative.
    ret         # Return.
```
[Answer]
# [05AB1E (legacy)](https://github.com/Adriandmen/05AB1E/tree/fb4a2ce2bce6660e1a680a74dd61b72c945e6c3b), ~~2~~ ~~1~~ 2 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
¬ßg
```
-1 byte by changing an explicit evaluate as Python (`.E`) to an implicit one (`¬ß`)  
+1 byte because apparently the default is truthy/falsey when it's unspecified. I was under the impression two distinguished values were the default, unless truthy/falsey was mentioned specifically.
Input wrapped in a list (as-is, since 05AB1E uses `"`/`"""` for string-quotes as well).  
Outputs `1` for truthy or nothing for falsey.
[Try it online](https://tio.run/##MzBNTDJM/f//0PL0//@jlUAgMTFRCQZiAQ) or [verify all test cases](https://tio.run/##bY5BDoIwEEX3PcWkYWcEiXFjwJ1uPYBhMcDENiEtkSaGE3kPL1ZLgWIIXXT@/Om83xI7YSs0cIFK1xTrDktJkGVwvd/s9/O0rjIm85S9hWwIXoQ1SMVqzQCoEhr2Cngkz8Cd0fZGaHWERLcmOZywTCkZkXHbrxIyiBwHoCEDXO7ylE9Ex1ZkHxx5wYZ7EkN1TdB8GTiF3vBn9v5aD1lQAROeenccTdB12GZW2N/IdwXn9eVLBfsB)
**Explanation:**
```
¬ß   # Cast the (implicit) input to a string, which is implicitly evaluated as Python‚Ä†
    # (if it was invalid Python, it will stop the program and output nothing)
 g  # Pop and push the length, to make the truthy cases explicit 1
    # (after which the truthy case is output implicitly with trailing newline)
```
‚Ä† This only applies to the legacy version of 05AB1E, which is build in Python. In the new version of 05AB1E (build in Elixir), this wouldn't work.
---
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 34 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
ŒîU17SbŒµXr¬°D¬¨√µQ¬©sg3@*i¬¶¬¶y√Ω√´X}}¬Æ√®}√µQ
```
Less boring approach without Python eval. Uses `1` instead of `"` in the inputs.  
Not the shortest approach, but at least it works. ü§∑
[Try it online](https://tio.run/##yy9OTMpM/f//3JRQQ/PgpHNbI4oPLXQ5tObw1sBDK4vTjR20Mg8tO7Ss8vDew6sjamsPrTu8ohYo9/@/IQgkJiYawsB/Xd28fN2cxKpKAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeX/c1NCDc2Dk85tjSg@tNDl0JrDWwMPrSxON3bQyjy07NCyysN7D6@OqK09tO7wilqg3H@d/9FKhomGSjogEsoA0UAOnG2IkACyEsECYAATQ@KCDUEYBTcGrhRJj5KOAlAFRBnUAnSLsdoLNwJTDEglwnQjbAKJQlmx/3V18/J1cxKrKgE).
**Explanation:**
```
Œî                   # Continue until the result no longer changes
                    # (using the implicit input-string in the first iteration):
 U                  #  Pop the current string, and store it in variable `X`
 17S                #  Push pair [1,7]
    b               #  Convert each to binary: [1,111] (these are the quotes to check)
     Œµ              #  Map over them:
      X             #   Push string `X`
       s            #   Swap so the current (binary) quote is at the top
        ¬°           #   Split string `X` on this single/triple (binary) quote
         D          #   Duplicate the split list
          ¬¨         #   Push its first item (without popping)
           √µQ       #   Check that the first item is an empty string
                    #   (which means string `X` starts with the current (binary) quote)
             ¬©      #   Store this 0 or 1 in variable `¬Æ` (without popping)
         s          #   Swap so the split list is at the top again
          g         #   Pop and push its length
           3@       #   Check that this length is >=3
                    #   (which means there is a matching closing quote)
              *i    #   If both checks are truthy:
                ¬¶   #    Remove the empty first string
                 ¬¶  #    As well as the second string
                y√Ω  #    Then join it with the (binary) quote again
               √´    #   Else:
                X   #    Simply keep `X` as is
               }    #   Close the if-else statement
     }              #  Close the map
      ¬Æ             #  Push the last `¬Æ` result for the triple-quote
       √®            #  0-based index this check into the pair
}                   # After the loop:
 √µQ                 # Check if what remains is an empty string
                    # (after which the result is output implicitly)
```
[Answer]
# [Whython](https://github.com/pxeger/whython), 20 bytes
```
lambda s:eval(s)+s?0
```
Just getting the obvious out of the way.
[Attempt This Online!](https://ato.pxeger.com/run?1=m728PKOyJCM_b8HiNNuYpaUlaboWW3ISc5NSEhWKrVLLEnM0ijW1i-0NIFI3X6TlFymUpBaXJCcWpypk5imoq6tzKSUqgTCYApFAJpSlBBME0olgLhhwKSEBqFaYARDNiVxgc7jQjcNiGtQwdBEuoMv0ikuKMgs0NPWKC3IyS3Iy81KLNTStuBQUCooy80o0YP7QUVDStVPSUUiDi2hqQvy7YAGEBgA)
### Explanation
Whython is mostly Python 3, but with a couple added features. Here, we use the rescue operator `?`, which returns its left operand unless it raises an exception, in which case it returns its right operand instead. So if the argument `s` represents a valid string, `eval(s)` returns that string. Since the string can be empty, we concatenate `s` to it to make sure the result is nonempty and therefore truthy. If `s` is not a valid string, `eval(s)` errors, so we return `0` (falsey) instead.
[Answer]
# [GolfScript](http://www.golfscript.com/golfscript/), 18 bytes
```
'"""'/['"']+2%{~}%
```
[Try it online!](https://tio.run/##S8/PSStOLsosKPn/X11JSUldP1pdST1W20i1uq5W9f9/oFCiEgA "GolfScript ‚Äì Try It Online")
Split on ````` and eval each. Why 18 bytes though? :(
[Answer]
# Regex (Perl or PCRE), 21 bytes
```
^(?>("("")?+).*?\1)+$
```
[Test online on Regex101](https://regex101.com/r/bqab2U/1)
The idea to use a backreference was inspired by @Neil's answer. I wrote the rest myself, but most of it ended up the same (probably because there's only one shortest way to express the algorithm, so two golfers will come to the same conclusions).
The Regex101 link uses the `/gm` flags in order to test multiple inputs at once ‚Äì the problem as stated takes only a single input, so those flags aren't required and aren't part of the submission. (The existence of Regex101 establishes "regex" as a valid programming language by itself for the purposes of this site, as Regex101 acts as an interpreter for the language.)
## Explanation
```
^(?>("("")?+).*?\1)+$
^                   $    Only the input as a whole matches
 (                )+     The input must consist of one or more of:
    (       )              a group named \1, which consists of
     "                     one double quote,
      ("")                 followed by two more double quotes
          ?+                 if they are present at that point in the input,
             .*            followed by any number of any characters,
               ?             the shortest number which leads to a match,
                \1         followed by another copy of \1,
  ?>                     but try only the first possibility for each block
```
Here, each block has its own `\1`, i.e. the delimiter is allowed to be different for each block.
Normally, regexes can backtrack if one potential parse doesn't work, to try a different potential parse. This solution therefore has to contain a couple of backtracking-blockers in order to ensure that if Python would reject a parse, we also reject the input rather than backtracking:
* The `+` on `"("")?+` means that if three double-quotes are present in a row at that point of the input, all three double-quotes must be included in `\1`, the variable that holds the delimeter; the regex engine isn't allowed to go back and try with just one. This ensures that `"""a"` is correctly rejected, by preventing it being parsed as `""``"a"`.
* The `?>` means that once the first possibility for a string in the input has been discovered, that must be used as a section when matching for the string as a whole; the regex engine isn't allowed to go back and try a different section. Because of the `?` on `.*?`, sections are tested shortest to longest, so in this situation, the restriction imposed by `?>` can equivalently be stated as "if any prefix of the input is a valid string, that prefix must be interpreted as the string, don't look for any longer prefixes that might also be valid". This ensures that `"""a""""` is correctly rejected, by preventing it being viewed as `a"` within triple quotes (because `"""a"""` is a valid string that will be tested first).
# Regex (Perl or PCRE, no backreferences), 25 bytes
```
^(?>""".*?"""|"a+"|""$)+$
```
[Test online on Regex101](https://regex101.com/r/1CiUt2/1)
The thing that first inspired me to try answering this question with regex is that the set of allowed answers is a regular expression in the mathematical sense ‚Äì you can solve it purely with a finite state automaton. Here's an answer that demonstrates that.
It's pretty similar to the previous solution, except that there are separate cases for the `"` and `"""` delimiters. When using `"""`, the string can be empty; as in the previous answer, there's a backtracking-blocker (here `?>`) present to ensure that only the first `"""` is matched. When using `"`, then the regex needs to disallow possibilities that would start with `"""`. The only such possibility is an empty string followed by another string, so we ensure that either the string is nonempty (i.e. it contains `a+`, i.e. one or more `a`), or else that we have an empty string at the end of input (written in regex syntax as `""$`).
As a side note, the fact that the set of answers is a regular expression in the mathematical sense implies that problem can also be solved without backtracking-blockers at all (meaning that no evaluation order hints are required either). However, the solution would likely be somewhat longer; the best I've found is `^("""("{0,2}a)*"""|"a+"|""$)+$` at 30 bytes.
[Answer]
# [Turing Machine Code](http://morphett.info/turing/turing.html), 147 bytes
```
0 " _ r 1
0 _ _ * haltA
1 " _ r 2
1 a _ r S
2 " _ r T
2 _ _ * haltA
S a _ r S
S " _ r 0
T a _ r T
T " _ r 3
3 " _ r 4
3 a _ r T
4 " _ r 0
4 a _ r T
```
[Try it online!](https://morphett.info/turing/turing.html?a7fc84e1a5bc55b05cc1923a3969573d)
The input string is valid iff the machine halts on state `haltA`.
Note that the machine is basically a DFA.
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 84 bytes
```
n;S;g(char*s){n=bcmp(s,S="\"\"\"",3)?1:3;S=strstr(s+n,S+3-n);n=*s-34?!*s:S&&g(S+n);}
```
[Try it online!](https://tio.run/##bU3LbsIwEDx7v8K1BLITR2pxT1gRH@Fj6cF1wUQiFsKROKD8OmZjHAnRrh@zj5lZ13jnUgraaM/dwZ6rKK6h/XH9iUdpWrbNh0klNh9rpU0bhzNeHusgTa2aIHRoq9ioz81bFddmufTc1NgdUxcG2tsucHEFMhWo64L/Wr1/ayCXQ3fcUe53Q@SPgRAUieSE@bDnbPFLKV1Eug1MUj9zZHERaEGAjDAmZhngyzD9mJaMzU1Em8scwJ6iSGeDIoYXJg4gW8Prhn8WFNWflWDhSTDVD7y5/dH6mJpLanq1ugM "C (gcc) ‚Äì Try It Online")
Require 32-bit or +5 byte `long` 
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 1 byte
```
‚Ä†
```
[Try it Online!](https://vyxal.pythonanywhere.com/#WyJBIiwiIiwi4oCgIiwiIiwiW1wiYVwiXVxuW1wiYVwiXCJhXCJdXG5bXCJcIlwiXCJdXG5bXCJhXVxuW1wiXCJcIlwiXCJhYWFcIlwiXCJcIlwiXCJcIlwiXCJdXG5bYV0iXQ==)
Python `eval` and inputs as a list. Returns a a list `[0]` if true and an empty list `[]` if false.
[Answer]
# Python (built-in), 4 bytes (built-in), JS (TODO)
Because I'm evil and mousetail allowed me to.
```
exec
```
~~I'll add a C answer later.~~ A C answer has already been added, so I'll add a JS answer by 19 November 2022.
Note: there are other answers that deserve your upvote, rather than this one.
]