I am not sure if I brought this issue on because I tinkered with my card template, or what. However, I found that the text replacement fails if card fields are nested. That is, if div tags are nested, the regular expression fails to match them correctly.
This problem is not surprising, however, because regular expressions aren't actually capable of paren-balancing (extended regexes can, but it's messy). You need at least a stack-based solution, I think.
Since you have balanced tags it's really similar to a calculator. An outline of how to build the modified text would be:
- Check each character in the template (or word, whatever) and insert it unless it meets point 2 below.
- Finding an opening div tag means push the changed version (the one with the new JS) onto the stack plus a unique token, and insert the changed, unfinished version with this token instead of the field name we need.
- When you find a matching fieldname, find the div tag on the top of the stack, get its token, and find that token in the text you've already accumulated and replace it with the fieldname. Push the fieldname onto the stack. Insert the fieldname.
- When a closing div tag is found, pop the top two elements off the stack and insert them into the text along with the closing div tag.
- All other text is just inserted into the replacement text as normal.
If I understand the goal correctly, this solves the problem and shouldn't be too slow. Considering that the size of the template text is only maybe a thousand characters, searching character-wise shouldn't be an issue. It can maybe be improved by splitting the text on "<div", but I bet Python does a character-wise search anyway.