   (-> text
       (replace #"\s*\([^)]+\)" "")
       (replace #"\s*\[[^\]]+\]" "")))
+
+(def name-like?
+  "Detect if `text` looks like a name.
+  It needs to have 2 capitalized words, e.g., 'Aaaa Aaaaaa'."
+  (let [name-regex (re-pattern (str "^" uppercase lowercase "+\\s+" uppercase lowercase "+$"))]
+    (fn [text]
+      (re-matches name-regex text))))
+
+(def name->regex
+  "Convert a name into a regular expression that matches it with a middle name added."
+  (let [name-regex (str uppercase lowercase "+")
+        apostrophes-regex "[\"']?"]
+    (fn [text]
+      (let [[first-name last-name] (take 2 (tokenize text))]
+        (re-pattern (str first-name "\\s+(" apostrophes-regex
+                         name-regex apostrophes-regex "\\s+){1,2}" last-name))))))
 
 (defn remove-punctuation
   "Remove punctuation from s.

        clean-label (clear-label label)
        tokens (clear-tokens (tokenize clean-label))
        abbreviation (abbreviate-tokens tokens)
        ; Sort surface forms from the longest to the shortest, so that we first replace
        ; the longer matches. 
        surface-forms (if despoilerify?
                          (sort-by (comp - count)
                               ; Filter empty and < 2 characters long surface forms
                               (distinct (conj (filter (every-pred (complement (partial re-matches #"^\s+$"))
                                                                   (comp (partial < 2) count))
                                                       (split surfaceForms "|"))
                                              clean-label
                                              label)))
                          [label clean-label])]
    (assoc item
           :abbreviation abbreviation
           :description (-> description

                                        placeholder))
                                    tail
                                    tail-range))))
              tokens
              (map range tail-offsets (rest tail-offsets))))))
