diff --git a/exercises/cloze_exercise.php b/exercises/cloze_exercise.php
index b2852d5cf606ed0980889bcf2c74ee4291a14ef8..9843971bd2acc53c7a55a633d9b046f51b375c87 100644
--- a/exercises/cloze_exercise.php
+++ b/exercises/cloze_exercise.php
@@ -369,7 +369,7 @@ class cloze_exercise extends Exercise
                 foreach ($this->task['answers'][$blank] as $answer) {
                     $answer_text = $answer['text'];
 
-                    if (preg_match('/^([":*~]|$|.*\|)/', $answer_text)) {
+                    if (preg_match('/^$|^[":*~]|\||\]\]/', $answer_text)) {
                         $answer_text = '"' . $answer_text . '"';
                     }
 
@@ -406,7 +406,7 @@ class cloze_exercise extends Exercise
         $question = Studip\Markup::purifyHtml($question);
 
         // $question_array contains text elements and blanks (surrounded by [[ and ]]).
-        $parts = preg_split('/(\[\[.*?\]\])/s', $question, -1, PREG_SPLIT_DELIM_CAPTURE);
+        $parts = preg_split('/(\[\[(?:".*?"|.)*?\]\])/s', $question, -1, PREG_SPLIT_DELIM_CAPTURE);
 
         foreach ($parts as $part) {
             if (preg_match('/^\[\[(.*)\]\]$/s', $part, $matches)) {
@@ -424,7 +424,7 @@ class cloze_exercise extends Exercise
                 }
 
                 if ($part !== '') {
-                    preg_match_all('/( *[*~]?".*?" *|[^|]*)\|/', $part . '|', $matches);
+                    preg_match_all('/((?:".*?"|[^|])*)\|/', $part . '|', $matches);
 
                     foreach ($matches[1] as $answer) {
                         $answer = trim($answer);