So I realised my first try above did not take indentation into account. Here is the snippet I came up with. It's good enough for my purpose. So far, in spite of the limitations described below, I've been able to use it in a satisfactory manner.
[
{
"key": "alt+shift+a",
"command": "editor.action.insertSnippet",
"args": {
// Indentation-saving snippet
// MATCH
// ^ Beginning of selected text
// ( *) $1 is a possible indentation that is to be reused for delimiters and content
// ('''\n *)? $2 is a possible opening delimiter, including following line break and indentation
// (.*?) $3 is a possible content (non-greedy)
// (\n *''')? $4 is a possible closing delimiter, including previous line break and indentation
// $ End of selected text
// SUBSTITUTION
// $1 If there was an indentation, indent the opening delimiter
// ${2:?\n:'''\n} If there was an opening delimiter, replace it with a line break, otherwise make a delimiter and line break
// $1 If there was an indentation, indent the content
// $3\n The content and a line break
// $1 If there was an indentation, indent the closing delimiter
// ${4:?\n:'''} If there was a closing delimiter, replace it with a line break, otherwise make a linebreak and a delimiter
// LIMITATIONS
// The selection must be the entire lines of the content to comment in / out
// Line breaks are created because we can't replace a group by nothing in this REGEX implementation
"snippet": "${TM_SELECTED_TEXT/^( *)('''\n *)?(.*?)(\n *''')?$/$1${2:?\n:'''\n}$1$3\n$1${4:?\n:'''}/s}"
},
"when": "editorTextFocus && editorHasSelection && editorLangId == 'python'"
}
]
My settings generate indentation as spaces, but I assume it could be adapted to tabs.
I'm accepting @rich neadle's reply as the answer, namely this did answer the initial question:
I am not aware of if-else if-else if-else then replacements that I could build with regex