Repository: facelessuser/pymdown-extensions

Issue:
`betterem` extension does not understand italic nested inside of bold, if italic is used later on the same line
### Description

```python
import markdown

markdown.markdown("***italic and bold* bold**", extensions=['pymdownx.betterem'])
# '<p><strong><em>italic and bold</em> bold</strong></p>'

markdown.markdown("***italic and bold* bold**: foo bar *italic*", extensions=['pymdownx.betterem'])
# '<p><em><strong>italic and bold* bold</strong>: foo bar *italic</em></p>'

# Workarounds:
markdown.markdown("__*italic and bold* bold__: foo bar *italic*", extensions=['pymdownx.betterem'])
markdown.markdown("***italic and bold* bold**: foo bar _italic_", extensions=['pymdownx.betterem'])
```

I'm currently using one of the workarounds, but maybe this should still be addressed considering it can be pretty confusing.

### Minimal Reproduction

see above

### Version(s) & System Info

- Package Version: 10.12

Hints from issue comments:
@facelessuser: This is most likely a sequence problem with `***text*text**` vs `***text**text*`. I imagine we need to swap priority.@facelessuser: I think I have a fix locally. I'll get a PR up and merged over the weekend.@facelessuser: I ended up running some more exhaustive tests on these complex, mixed cases, above and beyond the cases in the opening post. I ended up refactoring how cases like these are generally treated. Generally, the patterns needed to be more limited to keep them from greedily creating non-intuitive matches. Moving forward, these should behave more sanely.

Solution patch:
diff --git a/docs/src/markdown/about/changelog.md b/docs/src/markdown/about/changelog.md
index acab38904..d50e6859a 100644
--- a/docs/src/markdown/about/changelog.md
+++ b/docs/src/markdown/about/changelog.md
@@ -3,6 +3,7 @@
 ## 10.12.1
 
 -   **FIX**: Snippets: Fix issue where when non sections of files are included, section labels are not stripped.
+-   **FIX**: BetterEm: Fixes for complex cases.
 
 ## 10.12
 
diff --git a/pymdownx/betterem.py b/pymdownx/betterem.py
index 0277c9b66..f6a4e4b0d 100644
--- a/pymdownx/betterem.py
+++ b/pymdownx/betterem.py
@@ -29,6 +29,8 @@
 
 SMART_UNDER_CONTENT = r'(.+?_*?)'
 SMART_STAR_CONTENT = r'(.+?\**?)'
+SMART_STAR_LIMITED_CONTENT = r'((?:[^\*]|(?<=\w)\*+?(?=\w)|(?<=\s)\*+?(?=\s))+?)'
+SMART_UNDER_LIMITED_CONTENT = r'((?:[^_]|(?<=[^\W_])_+?(?=[^\W_])|(?<=\s)_+?(?=\s))+?)'
 UNDER_CONTENT = r'(_|(?:(?<=\s)_|[^_])+?)'
 UNDER_CONTENT2 = r'((?:[^_]|(?<!_{2})_)+?)'
 STAR_CONTENT = r'(\*|(?:(?<=\s)\*|[^\*])+?)'
@@ -42,15 +44,15 @@
 # ___strong,em___
 UNDER_STRONG_EM = r'(_{3})(?!\s)(_{1,2}|[^_]+?)(?<!\s)\1'
 # ***strong,em*strong**
-STAR_STRONG_EM2 = r'(\*{{3}})(?![\s\*]){}(?<!\s)\*{}(?<!\s)\*{{2}}'.format(STAR_CONTENT, STAR_CONTENT2)
+STAR_STRONG_EM2 = r'(\*{{3}})(?![\s\*]){}(?<!\s)\*{}(?<!\s)\*{{2}}'.format(STAR_CONTENT, STAR_CONTENT)
 # ___strong,em_strong__
-UNDER_STRONG_EM2 = r'(_{{3}})(?![\s_]){}(?<!\s)_{}(?<!\s)_{{2}}'.format(UNDER_CONTENT, UNDER_CONTENT2)
+UNDER_STRONG_EM2 = r'(_{{3}})(?![\s_]){}(?<!\s)_{}(?<!\s)_{{2}}'.format(UNDER_CONTENT, UNDER_CONTENT)
 # ***em,strong**em*
-STAR_EM_STRONG = r'(\*{{3}})(?![\s\*]){}(?<!\s)\*{{2}}{}(?<!\s)\*'.format(STAR_CONTENT2, STAR_CONTENT)
+STAR_EM_STRONG = r'(\*{{3}})(?![\s\*]){}(?<!\s)\*{{2}}{}(?<!\s)\*'.format(STAR_CONTENT, STAR_CONTENT)
 # **strong*em,strong***
 STAR_STRONG_EM3 = r'(\*{{2}})(?![\s\*]){}\*(?![\s\*]){}(?<!\s)\*{{3}}'.format(STAR_CONTENT, STAR_CONTENT)
 # ___em,strong__em_
-UNDER_EM_STRONG = r'(_{{3}})(?![\s_]){}(?<!\s)_{{2}}{}(?<!\s)_'.format(UNDER_CONTENT2, UNDER_CONTENT)
+UNDER_EM_STRONG = r'(_{{3}})(?![\s_]){}(?<!\s)_{{2}}{}(?<!\s)_'.format(UNDER_CONTENT, UNDER_CONTENT)
 # __strong_em,strong___
 UNDER_STRONG_EM3 = r'(_{{2}})(?![\s_]){}_(?![\s_]){}(?<!\s)_{{3}}'.format(UNDER_CONTENT, UNDER_CONTENT)
 # **strong**
@@ -58,13 +60,13 @@
 # __strong__
 UNDER_STRONG = r'(_{{2}})(?!\s){}(?<!\s)\1'.format(UNDER_CONTENT2)
 # *em **strong***
-STAR_EM_STRONG2 = r'(?<!\*)(\*)(?![\*\s]){}\*{{2}}{}\*{{3}}'.format(STAR_CONTENT, STAR_CONTENT2)
+STAR_EM_STRONG2 = r'(?<!\*)(\*)(?![\*\s]){}\*{{2}}{}\*{{3}}'.format(STAR_CONTENT, STAR_CONTENT)
 # _em __strong___
-UNDER_EM_STRONG2 = r'(?<!_)(_)(?![_\s]){}_{{2}}{}_{{3}}'.format(UNDER_CONTENT, UNDER_CONTENT2)
+UNDER_EM_STRONG2 = r'(?<!_)(_)(?![_\s]){}_{{2}}{}_{{3}}'.format(UNDER_CONTENT, UNDER_CONTENT)
 # Prioritize *value* when **value** is nested within
-STAR_EM2 = r'(?<!\*)(\*)(?![\*\s])(.+?)(?<![\*\s])(\*)(?!\*)'
+STAR_EM2 = r'(?<!\*)(\*)(?![\*\s])((?:[^\*]|\*{2,})+?)(?<![\*\s])(\*)(?!\*)'
 # Prioritize _value_ when __value__ is nested within
-UNDER_EM2 = r'(?<!_)(_)(?![_\s])(.+?)(?<![_\s])(_)(?!_)'
+UNDER_EM2 = r'(?<!_)(_)(?![_\s])((?:[^_]|_{2,})+?)(?<![_\s])(_)(?!_)'
 # *emphasis*
 STAR_EM = r'(\*)(?!\s){}(?<!\s)\1'.format(STAR_CONTENT)
 # _emphasis_
@@ -75,20 +77,28 @@
 SMART_UNDER_STRONG_EM = r'(?<!\w)(_{{3}})(?![\s_]){}(?<!\s)\1(?!\w)'.format(SMART_UNDER_CONTENT)
 # SMART: ___strong,em_ strong__
 SMART_UNDER_STRONG_EM2 = \
-    r'(?<!\w)(_{{3}})(?![\s_]){}(?<!\s)_(?!\w){}(?<!\s)_{{2}}(?!\w)'.format(SMART_UNDER_CONTENT, SMART_UNDER_CONTENT)
+    r'(?<!\w)(_{{3}})(?![\s_]){}(?<!\s)_(?!\w){}(?<!\s)_{{2}}(?!\w)'.format(
+        SMART_UNDER_LIMITED_CONTENT, SMART_UNDER_LIMITED_CONTENT
+    )
 # SMART: ___em,strong__ em_
 SMART_UNDER_EM_STRONG = \
-    r'(?<!\w)(_{{3}})(?![\s_]){}(?<!\s)_{{2}}(?!\w){}(?<!\s)_(?!\w)'.format(SMART_UNDER_CONTENT, SMART_UNDER_CONTENT)
+    r'(?<!\w)(_{{3}})(?![\s_]){}(?<!\s)_{{2}}(?!\w){}(?<!\s)_(?!\w)'.format(
+        SMART_UNDER_LIMITED_CONTENT, SMART_UNDER_LIMITED_CONTENT
+    )
 # SMART: __strong__
 SMART_UNDER_STRONG = r'(?<!\w)(_{{2}})(?![\s_]){}(?<!\s)\1(?!\w)'.format(SMART_UNDER_CONTENT)
 # SMART: _em_
 SMART_UNDER_EM = r'(?<!\w)(_)(?![\s_]){}(?<!\s)\1(?!\w)'.format(SMART_UNDER_CONTENT)
 # SMART: Prioritize _value_ when __value__ is nested within
-SMART_UNDER_EM2 = r'(?<![\w_])(_)(?![_\s])(.+?)(?<![_\s])(_)(?![_\w])'
+SMART_UNDER_EM2 = r'(?<![\w_])(_)(?![_\s])((?:[^_]|_{2,})+?)(?<![_\s])(_)(?!\w)'
 # SMART: _em __strong___
 SMART_UNDER_EM_STRONG2 = \
     r'(?<!\w)(_)(?![\s_]){}(?<!\w)_{{2}}(?![\s_]){}(?<!\s)_{{3}}(?!\w)'.format(
-        SMART_UNDER_CONTENT, SMART_UNDER_CONTENT
+        SMART_UNDER_LIMITED_CONTENT, SMART_UNDER_LIMITED_CONTENT
+    )
+SMART_UNDER_STRONG_EM3 = \
+    r'(?<!\w)(_{{2}})(?![\s_]){}(?<!\w)_(?![\s_]){}(?<!\s)_{{3}}(?!\w)'.format(
+        SMART_UNDER_LIMITED_CONTENT, SMART_UNDER_LIMITED_CONTENT
     )
 
 # Smart rules for when "smart asterisk" is enabled
@@ -98,13 +108,13 @@
 )
 # SMART: ***strong,em* strong**
 SMART_STAR_STRONG_EM2 = \
-    r'(?:(?<=_)|(?<![\w\*]))(\*{{3}})(?![\s\*]){}(?<!\s)\*(?:(?=_)|(?![\w\*])){}(?<!\s)\*{{2}}(?:(?=_)|(?![\w\*]))'.format(
-        SMART_STAR_CONTENT, SMART_STAR_CONTENT
+    r'(?:(?<=_)|(?<![\w\*]))(\*{{3}})(?![\s\*]){}(?<![\s\*])\*(?:(?=_)|(?![\w\*])){}(?<![\s\*])\*{{2}}(?:(?=_)|(?![\w\*]))'.format(
+        SMART_STAR_LIMITED_CONTENT, SMART_STAR_LIMITED_CONTENT
     )
 # SMART: ***em,strong** em*
 SMART_STAR_EM_STRONG = \
-    r'(?:(?<=_)|(?<![\w\*]))(\*{{3}})(?![\s\*]){}(?<!\s)\*{{2}}(?:(?=_)|(?![\w\*])){}(?<!\s)\*(?:(?=_)|(?![\w\*]))'.format(
-        SMART_STAR_CONTENT, SMART_STAR_CONTENT
+    r'(?:(?<=_)|(?<![\w\*]))(\*{{3}})(?![\s\*]){}(?<![\s\*])\*{{2}}(?:(?=_)|(?![\w\*])){}(?<![\s\*])\*(?:(?=_)|(?![\w\*]))'.format(
+        SMART_STAR_LIMITED_CONTENT, SMART_STAR_LIMITED_CONTENT
     )
 # SMART: **strong**
 SMART_STAR_STRONG = r'(?:(?<=_)|(?<![\w\*]))(\*{{2}})(?![\s\*]){}(?<!\s)\1(?:(?=_)|(?![\w\*]))'.format(
@@ -113,13 +123,17 @@
 # SMART: *em*
 SMART_STAR_EM = r'(?:(?<=_)|(?<![\w\*]))(\*)(?![\s\*]){}(?<!\s)\1(?:(?=_)|(?![\w\*]))'.format(SMART_STAR_CONTENT)
 # SMART: Prioritize *value* when **value** is nested within
-SMART_STAR_EM2 = r'(?<![\w\*])(\*)(?![\*\s])(.+?)(?<![\*\s])(\*)(?![\*\w])'
+SMART_STAR_EM2 = r'(?:(?<=_)|(?<![\w\*]))(\*)(?![\*\s])((?:[^\*]|\*{2,})+?)(?<![\*\s])(\*)(?:(?=_)|(?![\w\*]))'
 # SMART: *em **strong***
 SMART_STAR_EM_STRONG2 = \
     r'(?:(?<=_)|(?<![\w\*]))(\*)(?![\s\*]){}(?:(?<=_)|(?<![\w\*]))\*{{2}}(?![\s\*]){}(?<!\s)\*{{3}}(?:(?=_)|(?![\w\*]))'.format(
-        SMART_STAR_CONTENT, SMART_STAR_CONTENT
+        SMART_STAR_LIMITED_CONTENT, SMART_STAR_LIMITED_CONTENT
+    )
+# SMART: **em *strong***
+SMART_STAR_STRONG_EM3 = \
+    r'(?:(?<=_)|(?<![\w\*]))(\*{{2}})(?![\s\*]){}(?:(?<=_)|(?<![\w\*]))\*(?![\s\*]){}(?<![\s\*])\*{{3}}(?:(?=_)|(?![\w\*]))'.format(
+        SMART_STAR_LIMITED_CONTENT, SMART_STAR_LIMITED_CONTENT
     )
-
 
 class AsteriskProcessor(util.PatternSequenceProcessor):
     """Emphasis processor for handling strong and em matches."""
@@ -130,8 +144,8 @@ class AsteriskProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(STAR_STRONG_EM2, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
         util.PatSeqItem(re.compile(STAR_STRONG_EM3, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
         util.PatSeqItem(re.compile(STAR_STRONG, re.DOTALL | re.UNICODE), 'single', 'strong'),
-        util.PatSeqItem(re.compile(STAR_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(STAR_EM_STRONG2, re.DOTALL | re.UNICODE), 'double2', 'em,strong'),
+        util.PatSeqItem(re.compile(STAR_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(STAR_EM, re.DOTALL | re.UNICODE), 'single', 'em')
     ]
 
@@ -143,9 +157,10 @@ class SmartAsteriskProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(SMART_STAR_STRONG_EM, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
         util.PatSeqItem(re.compile(SMART_STAR_EM_STRONG, re.DOTALL | re.UNICODE), 'double', 'em,strong'),
         util.PatSeqItem(re.compile(SMART_STAR_STRONG_EM2, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
+        util.PatSeqItem(re.compile(SMART_STAR_STRONG_EM3, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
         util.PatSeqItem(re.compile(SMART_STAR_STRONG, re.DOTALL | re.UNICODE), 'single', 'strong'),
-        util.PatSeqItem(re.compile(SMART_STAR_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(SMART_STAR_EM_STRONG2, re.DOTALL | re.UNICODE), 'double2', 'em,strong'),
+        util.PatSeqItem(re.compile(SMART_STAR_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(SMART_STAR_EM, re.DOTALL | re.UNICODE), 'single', 'em')
     ]
 
@@ -159,8 +174,8 @@ class UnderscoreProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(UNDER_STRONG_EM2, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
         util.PatSeqItem(re.compile(UNDER_STRONG_EM3, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
         util.PatSeqItem(re.compile(UNDER_STRONG, re.DOTALL | re.UNICODE), 'single', 'strong'),
-        util.PatSeqItem(re.compile(UNDER_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(UNDER_EM_STRONG2, re.DOTALL | re.UNICODE), 'double2', 'em,strong'),
+        util.PatSeqItem(re.compile(UNDER_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(UNDER_EM, re.DOTALL | re.UNICODE), 'single', 'em')
     ]
 
@@ -172,9 +187,10 @@ class SmartUnderscoreProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(SMART_UNDER_STRONG_EM, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
         util.PatSeqItem(re.compile(SMART_UNDER_EM_STRONG, re.DOTALL | re.UNICODE), 'double', 'em,strong'),
         util.PatSeqItem(re.compile(SMART_UNDER_STRONG_EM2, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
+        util.PatSeqItem(re.compile(SMART_UNDER_STRONG_EM3, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
         util.PatSeqItem(re.compile(SMART_UNDER_STRONG, re.DOTALL | re.UNICODE), 'single', 'strong'),
-        util.PatSeqItem(re.compile(SMART_UNDER_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(SMART_UNDER_EM_STRONG2, re.DOTALL | re.UNICODE), 'double2', 'em,strong'),
+        util.PatSeqItem(re.compile(SMART_UNDER_EM2, re.DOTALL | re.UNICODE), 'single', 'em', True),
         util.PatSeqItem(re.compile(SMART_UNDER_EM, re.DOTALL | re.UNICODE), 'single', 'em')
     ]
 
diff --git a/pymdownx/caret.py b/pymdownx/caret.py
index 43422354d..747bc7ece 100755
--- a/pymdownx/caret.py
+++ b/pymdownx/caret.py
@@ -31,6 +31,7 @@
 from . import util
 
 SMART_CONTENT = r'(.+?\^*?)'
+SMART_LIMITED_CONTENT = r'((?:[^\^]|(?<=\w)\^+?(?=\w)|(?<=\s)\^+?(?=\s))+?)'
 CONTENT = r'(\^|[^\s]+?)'
 CONTENT2 = r'((?:[^\^]|(?<!\^{2})\^)+?)'
 
@@ -52,7 +53,7 @@
 # `^sup ^^sup,ins^^^`
 SUP_INS2 = r'(?<!\^)(\^)(?![\^\s]){}\^{{2}}{}\^{{3}}'.format(CONTENT, CONTENT)
 # Prioritize ^value^ when ^^value^^ is nested within
-SUP2 = r'(?<!\^)(\^)(?![\^\s])([^\s]+?)(?<![\^\s])(\^)(?!\^)'
+SUP2 = r'(?<!\^)(\^)(?![\^\s])((?:[^\^\s]|\^{2,})+?)(?<![\^\s])(\^)(?!\^)'
 
 # Smart rules for when "smart caret" is enabled
 # SMART: `^^^ins,sup^^^`
@@ -60,7 +61,7 @@
 # SMART: `^^^ins,sup^ ins^^`
 SMART_INS_SUP2 = \
     r'(\^{{3}})(?![\s\^]){}(?<!\s)\^(?:(?=_)|(?![\w\^])){}(?<!\s)\^{{2}}'.format(
-        CONTENT, SMART_CONTENT
+        CONTENT, SMART_LIMITED_CONTENT
     )
 # SMART: `^^^sup,ins^^ sup^`
 SMART_SUP_INS = \
@@ -74,6 +75,11 @@
     r'(?<!\^)(\^)(?![\s\^]){}(?:(?<=_)|(?<![\w\^]))\^{{2}}(?![\s\^]){}(?<!\s)\^{{3}}'.format(
         CONTENT, CONTENT
     )
+# SMART: `^^sup ^sup,ins^^^`
+SMART_INS_SUP3 = \
+    r'(?<!\^)(\^{{2}})(?![\s\^]){}(?:(?<=_)|(?<![\w\^]))\^(?![\s\^]){}(?<!\s)\^{{3}}'.format(
+        SMART_LIMITED_CONTENT, CONTENT
+    )
 
 
 class CaretProcessor(util.PatternSequenceProcessor):
@@ -85,8 +91,8 @@ class CaretProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(INS_SUP2, re.DOTALL | re.UNICODE), 'double', 'ins,sup'),
         util.PatSeqItem(re.compile(INS_SUP3, re.DOTALL | re.UNICODE), 'double2', 'ins,sup'),
         util.PatSeqItem(re.compile(INS, re.DOTALL | re.UNICODE), 'single', 'ins'),
-        util.PatSeqItem(re.compile(SUP2, re.DOTALL | re.UNICODE), 'single', 'sup', True),
         util.PatSeqItem(re.compile(SUP_INS2, re.DOTALL | re.UNICODE), 'double2', 'sup,ins'),
+        util.PatSeqItem(re.compile(SUP2, re.DOTALL | re.UNICODE), 'single', 'sup', True),
         util.PatSeqItem(re.compile(SUP, re.DOTALL | re.UNICODE), 'single', 'sup')
     ]
 
@@ -98,9 +104,10 @@ class CaretSmartProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(SMART_INS_SUP, re.DOTALL | re.UNICODE), 'double', 'ins,sup'),
         util.PatSeqItem(re.compile(SMART_SUP_INS, re.DOTALL | re.UNICODE), 'double', 'sup,ins'),
         util.PatSeqItem(re.compile(SMART_INS_SUP2, re.DOTALL | re.UNICODE), 'double', 'ins,sup'),
+        util.PatSeqItem(re.compile(SMART_INS_SUP3, re.DOTALL | re.UNICODE), 'double2', 'ins,sup'),
         util.PatSeqItem(re.compile(SMART_INS, re.DOTALL | re.UNICODE), 'single', 'ins'),
-        util.PatSeqItem(re.compile(SUP2, re.DOTALL | re.UNICODE), 'single', 'sup', True),
         util.PatSeqItem(re.compile(SMART_SUP_INS2, re.DOTALL | re.UNICODE), 'double2', 'sup,ins'),
+        util.PatSeqItem(re.compile(SUP2, re.DOTALL | re.UNICODE), 'single', 'sup', True),
         util.PatSeqItem(re.compile(SUP, re.DOTALL | re.UNICODE), 'single', 'sup')
     ]
 
diff --git a/pymdownx/tilde.py b/pymdownx/tilde.py
index f557e318a..e58c1f6a7 100755
--- a/pymdownx/tilde.py
+++ b/pymdownx/tilde.py
@@ -30,6 +30,7 @@
 from . import util
 
 SMART_CONTENT = r'(.+?~*?)'
+SMART_LIMITED_CONTENT = r'((?:[^~]|(?<=\w)~+?(?=\w)|(?<=\s)~+?(?=\s))+?)'
 CONTENT = r'(~|[^\s]+?)'
 CONTENT2 = r'((?:[^~]|(?<!~{2})~)+?)'
 
@@ -51,7 +52,7 @@
 # `~sub ~~sub,del~~~`
 SUB_DEL2 = r'(?<!~)(~)(?![~\s]){}~{{2}}{}~{{3}}'.format(CONTENT, CONTENT)
 # Prioritize ~value~ when ~~value~~ is nested within
-SUB2 = r'(?<!~)(~)(?![~\s])([^\s]+?)(?<![~\s])(~)(?!~)'
+SUB2 = r'(?<!~)(~)(?![~\s])((?:[^\s~]|~{2,})+?)(?<![~\s])(~)(?!~)'
 
 # Smart rules for when "smart tilde" is enabled
 # SMART: `~~~del,sub~~~`
@@ -59,7 +60,7 @@
 # SMART: `~~~del,sub~ del~~`
 SMART_DEL_SUB2 = \
     r'(~{{3}})(?![\s~]){}(?<!\s)~(?:(?=_)|(?![\w~])){}(?<!\s)~{{2}}'.format(
-        CONTENT, SMART_CONTENT
+        CONTENT, SMART_LIMITED_CONTENT
     )
 # SMART: `~~~sub,del~~ sub~`
 SMART_SUB_DEL = \
@@ -73,6 +74,11 @@
     r'(?<!~)(~)(?![\s~]){}(?:(?<=_)|(?<![\w~]))~{{2}}(?![\s~]){}(?<!\s)~{{3}}'.format(
         CONTENT, CONTENT
     )
+# SMART: `~sub ~~sub,del~~~`
+SMART_DEL_SUB3 = \
+    r'(?<!~)(~{{2}})(?![\s~]){}(?:(?<=_)|(?<![\w~]))~(?![\s~]){}(?<!\s)~{{3}}'.format(
+        SMART_LIMITED_CONTENT, CONTENT
+    )
 
 
 class TildeProcessor(util.PatternSequenceProcessor):
@@ -84,8 +90,8 @@ class TildeProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(DEL_SUB2, re.DOTALL | re.UNICODE), 'double', 'del,sub'),
         util.PatSeqItem(re.compile(DEL_SUB3, re.DOTALL | re.UNICODE), 'double2', 'del,sub'),
         util.PatSeqItem(re.compile(DEL, re.DOTALL | re.UNICODE), 'single', 'del'),
-        util.PatSeqItem(re.compile(SUB2, re.DOTALL | re.UNICODE), 'single', 'sub', True),
         util.PatSeqItem(re.compile(SUB_DEL2, re.DOTALL | re.UNICODE), 'double2', 'sub,del'),
+        util.PatSeqItem(re.compile(SUB2, re.DOTALL | re.UNICODE), 'single', 'sub', True),
         util.PatSeqItem(re.compile(SUB, re.DOTALL | re.UNICODE), 'single', 'sub')
     ]
 
@@ -97,9 +103,10 @@ class TildeSmartProcessor(util.PatternSequenceProcessor):
         util.PatSeqItem(re.compile(SMART_DEL_SUB, re.DOTALL | re.UNICODE), 'double', 'del,sub'),
         util.PatSeqItem(re.compile(SMART_SUB_DEL, re.DOTALL | re.UNICODE), 'double', 'sub,del'),
         util.PatSeqItem(re.compile(SMART_DEL_SUB2, re.DOTALL | re.UNICODE), 'double', 'del,sub'),
+        util.PatSeqItem(re.compile(SMART_DEL_SUB3, re.DOTALL | re.UNICODE), 'double2', 'del,sub'),
         util.PatSeqItem(re.compile(SMART_DEL, re.DOTALL | re.UNICODE), 'single', 'del'),
-        util.PatSeqItem(re.compile(SUB2, re.DOTALL | re.UNICODE), 'single', 'sub', True),
         util.PatSeqItem(re.compile(SMART_SUB_DEL2, re.DOTALL | re.UNICODE), 'double2', 'sub,del'),
+        util.PatSeqItem(re.compile(SUB2, re.DOTALL | re.UNICODE), 'single', 'sub', True),
         util.PatSeqItem(re.compile(SUB, re.DOTALL | re.UNICODE), 'single', 'sub')
     ]
 


Test patch:
diff --git a/tests/test_extensions/test_betterem.py b/tests/test_extensions/test_betterem.py
index a2a73f1a8..308da8529 100644
--- a/tests/test_extensions/test_betterem.py
+++ b/tests/test_extensions/test_betterem.py
@@ -46,28 +46,114 @@ def test_complex_multple_underscore_type_variant2(self):
             '<p>on the <strong>1-4 row</strong> of the AP Combat Table <strong><em>and</em></strong> receive</p>'
         )
 
-    def test_complex_em_strong_star(self):
-        """Test `*text **text***`."""
+    def test_complex_cases_star(self):
+        """Test some complex cases for asterisks."""
 
         self.check_markdown(
-            "*I'm italic. **I'm bold and italic.***",
-            "<p><em>I'm italic. <strong>I'm bold and italic.</strong></em></p>"
-        )
+            '''
+            ***I'm italic and bold* I am just bold.**
 
-    def test_complex_em_strong_under(self):
-        """Test `_text __text___`."""
+            ***I'm bold and italic!** I am just italic.*
 
-        self.check_markdown(
-            "_I'm italic. __I'm bold and italic.___",
-            "<p><em>I'm italic. <strong>I'm bold and italic.</strong></em></p>"
+            *italic and **italic bold*** and *italic*
+
+            **bold and *italic bold*** and *italic*
+
+            ***I'm italic and bold* I am just bold.** *italic*
+
+            ***I'm bold and italic!** I am just italic.* *italic*
+
+            *italic and **italic bold*** and italic*
+
+            **bold and *italic bold*** and bold*
+
+            *italic and **italic bold***
+
+            **bold and *italic bold***
+
+            *italic **italic bold** italic*
+
+            ***italic and bold* bold**: foo bar **italic**
+
+            ***italic and bold** italic* foo bar **italic**
+
+            *italic and **italic bold*** **italic**
+
+            **bold and *italic bold*** **italic**
+            ''',
+            '''
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and <em>italic</em></p>
+            <p><strong>bold and <em>italic bold</em></strong> and <em>italic</em></p>
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong> <em>italic</em></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em> <em>italic</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and italic*</p>
+            <p><strong>bold and <em>italic bold</em></strong> and bold*</p>
+            <p><em>italic and <strong>italic bold</strong></em></p>
+            <p><strong>bold and <em>italic bold</em></strong></p>
+            <p><em>italic <strong>italic bold</strong> italic</em></p>
+            <p><strong><em>italic and bold</em> bold</strong>: foo bar <strong>italic</strong></p>
+            <p><em><strong>italic and bold</strong> italic</em> foo bar <strong>italic</strong></p>
+            <p><em>italic and <strong>italic bold</strong></em> <strong>italic</strong></p>
+            <p><strong>bold and <em>italic bold</em></strong> <strong>italic</strong></p>
+            ''',
+            True
         )
 
-    def test_complex_strong_em_under(self):
-        """Test `__text _text___`."""
+    def test_complex_cases_underscore(self):
+        """Test some complex cases for underscore."""
 
         self.check_markdown(
-            "__I'm bold. _I'm bold and italic.___",
-            "<p><strong>I'm bold. <em>I'm bold and italic.</em></strong></p>"
+            '''
+            ___I'm italic and bold_ I am just bold.__
+
+            ___I'm bold and italic!__ I am just italic._
+
+            _italic and __italic bold___ and _italic_
+
+            __bold and _italic bold___ and _italic_
+
+            ___I'm italic and bold_ I am just bold.__ _italic_
+
+            ___I'm bold and italic!__ I am just italic._ _italic_
+
+            _italic and __italic bold___ and italic_
+
+            __bold and _italic bold___ and bold_
+
+            _italic and __italic bold___
+
+            __bold and _italic bold___
+
+            _italic __italic bold__ italic_
+
+            ___italic and bold_ bold__: foo bar __italic__
+
+            ___italic and bold__ italic_ foo bar __italic__
+
+            _italic and __italic bold___ __italic__
+
+            __bold and _italic bold___ __italic__
+            ''',
+            '''
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and <em>italic</em></p>
+            <p><strong>bold and <em>italic bold</em></strong> and <em>italic</em></p>
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong> <em>italic</em></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em> <em>italic</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and italic_</p>
+            <p><strong>bold and <em>italic bold</em></strong> and bold_</p>
+            <p><em>italic and <strong>italic bold</strong></em></p>
+            <p><strong>bold and <em>italic bold</em></strong></p>
+            <p><em>italic <strong>italic bold</strong> italic</em></p>
+            <p><strong><em>italic and bold</em> bold</strong>: foo bar <strong>italic</strong></p>
+            <p><em><strong>italic and bold</strong> italic</em> foo bar <strong>italic</strong></p>
+            <p><em>italic and <strong>italic bold</strong></em> <strong>italic</strong></p>
+            <p><strong>bold and <em>italic bold</em></strong> <strong>italic</strong></p>
+            ''',
+            True
         )
 
 
@@ -83,58 +169,112 @@ class TestBetterSmartAll(util.MdCase):
         }
     }
 
-    def test_smart_complex_cases_star(self):
-        """Test some complex cases with star."""
+    def test_complex_cases_star(self):
+        """Test some complex cases for asterisks."""
 
         self.check_markdown(
             '''
             ***I'm italic and bold* I am just bold.**
 
             ***I'm bold and italic!** I am just italic.*
+
+            *italic and **italic bold*** and *italic*
+
+            **bold and *italic bold*** and *italic*
+
+            ***I'm italic and bold* I am just bold.** *italic*
+
+            ***I'm bold and italic!** I am just italic.* *italic*
+
+            *italic and **italic bold*** and not italic*
+
+            **bold and *italic bold*** and not italic*
+
+            *italic and **italic bold***
+
+            **bold and *italic bold***
+
+            *italic **italic bold** italic*
+
+            ***italic and bold* bold**: foo bar **bold**
+
+            ***italic and bold** italic* foo bar **bold**
+
+            *italic and **italic bold*** **bold**
+
+            **bold and *italic bold*** **bold**
             ''',
             '''
             <p><strong><em>I'm italic and bold</em> I am just bold.</strong></p>
             <p><em><strong>I'm bold and italic!</strong> I am just italic.</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and <em>italic</em></p>
+            <p><strong>bold and <em>italic bold</em></strong> and <em>italic</em></p>
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong> <em>italic</em></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em> <em>italic</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and not italic*</p>
+            <p><strong>bold and <em>italic bold</em></strong> and not italic*</p>
+            <p><em>italic and <strong>italic bold</strong></em></p>
+            <p><strong>bold and <em>italic bold</em></strong></p>
+            <p><em>italic <strong>italic bold</strong> italic</em></p>
+            <p><strong><em>italic and bold</em> bold</strong>: foo bar <strong>bold</strong></p>
+            <p><em><strong>italic and bold</strong> italic</em> foo bar <strong>bold</strong></p>
+            <p><em>italic and <strong>italic bold</strong></em> <strong>bold</strong></p>
+            <p><strong>bold and <em>italic bold</em></strong> <strong>bold</strong></p>
             ''',
             True
         )
 
-    def test_smart_complex_cases_underscore(self):
-        """Test some complex cases with underscore."""
+    def test_complex_cases_underscore(self):
+        """Test some complex cases for underscore."""
 
         self.check_markdown(
             '''
             ___I'm italic and bold_ I am just bold.__
 
             ___I'm bold and italic!__ I am just italic._
-            ''',
-            '''
-            <p><strong><em>I'm italic and bold</em> I am just bold.</strong></p>
-            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em></p>
-            ''',
-            True
-        )
 
-    def test_smart_complex_em_strong_star(self):
-        """Test `*text **text***`."""
+            _italic and __italic bold___ and _italic_
 
-        self.check_markdown(
-            "*I'm italic. **I'm bold and italic.***",
-            "<p><em>I'm italic. <strong>I'm bold and italic.</strong></em></p>"
-        )
+            __bold and _italic bold___ and _italic_
 
-    def test_smart_complex_em_strong_under(self):
-        """Test `_text __text___`."""
+            ___I'm italic and bold_ I am just bold.__ _italic_
 
-        self.check_markdown(
-            "_I'm italic. __I'm bold and italic.___",
-            "<p><em>I'm italic. <strong>I'm bold and italic.</strong></em></p>"
-        )
+            ___I'm bold and italic!__ I am just italic._ _italic_
 
-    def test_complex_strong_em_under(self):
-        """Test `__text _text___`."""
+            _italic and __italic bold___ and not italic_
 
-        self.check_markdown(
-            "__I'm bold. _I'm bold and italic.___",
-            "<p><strong>I'm bold. <em>I'm bold and italic.</em></strong></p>"
+            __bold and _italic bold___ and not italic_
+
+            _italic and __italic bold___
+
+            __bold and _italic bold___
+
+            _italic __italic bold__ italic_
+
+            ___italic and bold_ bold__: foo bar __bold__
+
+            ___italic and bold__ italic_ foo bar __bold__
+
+            _italic and __italic bold___ __bold__
+
+            __bold and _italic bold___ __bold__
+            ''',
+            '''
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and <em>italic</em></p>
+            <p><strong>bold and <em>italic bold</em></strong> and <em>italic</em></p>
+            <p><strong><em>I'm italic and bold</em> I am just bold.</strong> <em>italic</em></p>
+            <p><em><strong>I'm bold and italic!</strong> I am just italic.</em> <em>italic</em></p>
+            <p><em>italic and <strong>italic bold</strong></em> and not italic_</p>
+            <p><strong>bold and <em>italic bold</em></strong> and not italic_</p>
+            <p><em>italic and <strong>italic bold</strong></em></p>
+            <p><strong>bold and <em>italic bold</em></strong></p>
+            <p><em>italic <strong>italic bold</strong> italic</em></p>
+            <p><strong><em>italic and bold</em> bold</strong>: foo bar <strong>bold</strong></p>
+            <p><em><strong>italic and bold</strong> italic</em> foo bar <strong>bold</strong></p>
+            <p><em>italic and <strong>italic bold</strong></em> <strong>bold</strong></p>
+            <p><strong>bold and <em>italic bold</em></strong> <strong>bold</strong></p>
+            ''',
+            True
         )
diff --git a/tests/test_extensions/test_caret.py b/tests/test_extensions/test_caret.py
index 3b642c9dd..2b8c51778 100644
--- a/tests/test_extensions/test_caret.py
+++ b/tests/test_extensions/test_caret.py
@@ -113,20 +113,59 @@ def test_case_11(self):
             True
         )
 
-    def test_complex_sup_ins_under(self):
-        """Test `^text ^^text^^^`."""
+    def test_complex_cases(self):
+        """Test some complex cases."""
 
         self.check_markdown(
-            R"^I'm\ sup.\ ^^I'm\ sup\ and\ insert.^^^",
-            "<p><sup>I'm sup. <ins>I'm sup and insert.</ins></sup></p>"
-        )
+            R'''
+            ^^^I'm\ insert\ and\ sup^ I am just insert.^^
 
-    def test_complex_del_sup_inser(self):
-        """Test `^^text ^text^^^`."""
+            ^^^I'm\ insert\ and\ sup!^^\ I\ am\ just\ sup.^
 
-        self.check_markdown(
-            R"^^I'm insert. ^I'm\ sup\ and\ insert.^^^",
-            "<p><ins>I'm insert. <sup>I'm sup and insert.</sup></ins></p>"
+            ^sup\ and\ ^^sup\ insert^^^ and ^sup^
+
+            ^^insert and ^sup\ insert^^^ and ^sup^
+
+            ^^^I'm\ sup\ and\ insert^ I am just insert.^^ ^sup^
+
+            ^^^I'm\ insert\ and\ sup!^^\ I\ am\ just\ sup.^ ^sup^
+
+            ^sup\ and\ ^^sup\ insert^^^ and not sup^
+
+            ^^insert and ^sup\ insert^^^ and not sup^
+
+            ^sup\ and\ ^^sup\ insert^^^
+
+            ^^insert and ^sup\ insert^^^
+
+            ^sup\ ^^sup\ insert^^\ sup^
+
+            ^^^sup\ and\ insert^ insert^^: foo bar ^^insert^^
+
+            ^^^sup\ and\ insert^^\ sup^ foo bar ^^insert^^
+
+            ^sup\ and\ ^^sup\ insert^^^ ^^insert^^
+
+            ^^insert and ^sup\ insert^^^ ^^insert^^
+            ''',
+            '''
+            <p><ins><sup>I'm insert and sup</sup> I am just insert.</ins></p>
+            <p><sup><ins>I'm insert and sup!</ins> I am just sup.</sup></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> and <sup>sup</sup></p>
+            <p><ins>insert and <sup>sup insert</sup></ins> and <sup>sup</sup></p>
+            <p><ins><sup>I'm sup and insert</sup> I am just insert.</ins> <sup>sup</sup></p>
+            <p><sup><ins>I'm insert and sup!</ins> I am just sup.</sup> <sup>sup</sup></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> and not sup^</p>
+            <p><ins>insert and <sup>sup insert</sup></ins> and not sup^</p>
+            <p><sup>sup and <ins>sup insert</ins></sup></p>
+            <p><ins>insert and <sup>sup insert</sup></ins></p>
+            <p><sup>sup <ins>sup insert</ins> sup</sup></p>
+            <p><ins><sup>sup and insert</sup> insert</ins>: foo bar <ins>insert</ins></p>
+            <p><sup><ins>sup and insert</ins> sup</sup> foo bar <ins>insert</ins></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> <ins>insert</ins></p>
+            <p><ins>insert and <sup>sup insert</sup></ins> <ins>insert</ins></p>
+            ''',
+            True
         )
 
 
@@ -232,18 +271,57 @@ def test_case_10(self):
             True
         )
 
-    def test_complex_sup_ins_under(self):
-        """Test `^text ^^text^^^`."""
+    def test_complex_cases(self):
+        """Test some complex cases."""
 
         self.check_markdown(
-            R"^I'm\ sup.\ ^^I'm\ sup\ and\ insert.^^^",
-            "<p><sup>I'm sup. <ins>I'm sup and insert.</ins></sup></p>"
-        )
+            R'''
+            ^^^I'm\ insert\ and\ sup^ I am just insert.^^
 
-    def test_complex_del_sup_inser(self):
-        """Test `^^text ^text^^^`."""
+            ^^^I'm\ insert\ and\ sup!^^\ I\ am\ just\ sup.^
 
-        self.check_markdown(
-            R"^^I'm insert. ^I'm\ sup\ and\ insert.^^^",
-            "<p><ins>I'm insert. <sup>I'm sup and insert.</sup></ins></p>"
+            ^sup\ and\ ^^sup\ insert^^^ and ^sup^
+
+            ^^insert and ^sup\ insert^^^ and ^sup^
+
+            ^^^I'm\ sup\ and\ insert^ I am just insert.^^ ^sup^
+
+            ^^^I'm\ insert\ and\ sup!^^\ I\ am\ just\ sup.^ ^sup^
+
+            ^sup\ and\ ^^sup\ insert^^^ and not sup^
+
+            ^^insert and ^sup\ insert^^^ and not sup^
+
+            ^sup\ and\ ^^sup\ insert^^^
+
+            ^^insert and ^sup\ insert^^^
+
+            ^sup\ ^^sup\ insert^^\ sup^
+
+            ^^^sup\ and\ insert^ insert^^: foo bar ^^insert^^
+
+            ^^^sup\ and\ insert^^\ sup^ foo bar ^^insert^^
+
+            ^sup\ and\ ^^sup\ insert^^^ ^^insert^^
+
+            ^^insert and ^sup\ insert^^^ ^^insert^^
+            ''',
+            '''
+            <p><ins><sup>I'm insert and sup</sup> I am just insert.</ins></p>
+            <p><sup><ins>I'm insert and sup!</ins> I am just sup.</sup></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> and <sup>sup</sup></p>
+            <p><ins>insert and <sup>sup insert</sup></ins> and <sup>sup</sup></p>
+            <p><ins><sup>I'm sup and insert</sup> I am just insert.</ins> <sup>sup</sup></p>
+            <p><sup><ins>I'm insert and sup!</ins> I am just sup.</sup> <sup>sup</sup></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> and not sup^</p>
+            <p><ins>insert and <sup>sup insert</sup></ins> and not sup^</p>
+            <p><sup>sup and <ins>sup insert</ins></sup></p>
+            <p><ins>insert and <sup>sup insert</sup></ins></p>
+            <p><sup>sup <ins>sup insert</ins> sup</sup></p>
+            <p><ins><sup>sup and insert</sup> insert</ins>: foo bar <ins>insert</ins></p>
+            <p><sup><ins>sup and insert</ins> sup</sup> foo bar <ins>insert</ins></p>
+            <p><sup>sup and <ins>sup insert</ins></sup> <ins>insert</ins></p>
+            <p><ins>insert and <sup>sup insert</sup></ins> <ins>insert</ins></p>
+            ''',
+            True
         )
diff --git a/tests/test_extensions/test_tilde.py b/tests/test_extensions/test_tilde.py
index 5eb06498e..130c8abd5 100644
--- a/tests/test_extensions/test_tilde.py
+++ b/tests/test_extensions/test_tilde.py
@@ -113,20 +113,59 @@ def test_case_11(self):
             True
         )
 
-    def test_complex_sub_del_under(self):
-        """Test `~text ~~text~~~`."""
+    def test_complex_cases(self):
+        """Test some complex cases."""
 
         self.check_markdown(
-            R"~I'm\ sub.\ ~~I'm\ sub\ and\ delete.~~~",
-            "<p><sub>I'm sub. <del>I'm sub and delete.</del></sub></p>"
-        )
+            R'''
+            ~~~I'm\ delete\ and\ sub~ I am just delete.~~
 
-    def test_complex_del_sub_under(self):
-        """Test `~~text ~text~~~`."""
+            ~~~I'm\ delete\ and\ sub!~~\ I\ am\ just\ sub.~
 
-        self.check_markdown(
-            R"~~I'm delete. ~I'm\ sub\ and\ delete.~~~",
-            "<p><del>I'm delete. <sub>I'm sub and delete.</sub></del></p>"
+            ~sub\ and\ ~~sub\ delete~~~ and ~sub~
+
+            ~~delete and ~sub\ delete~~~ and ~sub~
+
+            ~~~I'm\ sub\ and\ delete~ I am just delete.~~ ~sub~
+
+            ~~~I'm\ delete\ and\ sub!~~\ I\ am\ just\ sub.~ ~sub~
+
+            ~sub\ and\ ~~sub\ delete~~~ and not sub~
+
+            ~~delete and ~sub\ delete~~~ and not sub~
+
+            ~sub\ and\ ~~sub\ delete~~~
+
+            ~~delete and ~sub\ delete~~~
+
+            ~sub\ ~~sub\ delete~~\ sub~
+
+            ~~~sub\ and\ delete~ delete~~: foo bar ~~delete~~
+
+            ~~~sub\ and\ delete~~\ sub~ foo bar ~~delete~~
+
+            ~sub\ and\ ~~sub\ delete~~~ ~~delete~~
+
+            ~~delete and ~sub\ delete~~~ ~~delete~~
+            ''',
+            '''
+            <p><del><sub>I'm delete and sub</sub> I am just delete.</del></p>
+            <p><sub><del>I'm delete and sub!</del> I am just sub.</sub></p>
+            <p><sub>sub and <del>sub delete</del></sub> and <sub>sub</sub></p>
+            <p><del>delete and <sub>sub delete</sub></del> and <sub>sub</sub></p>
+            <p><del><sub>I'm sub and delete</sub> I am just delete.</del> <sub>sub</sub></p>
+            <p><sub><del>I'm delete and sub!</del> I am just sub.</sub> <sub>sub</sub></p>
+            <p><sub>sub and <del>sub delete</del></sub> and not sub~</p>
+            <p><del>delete and <sub>sub delete</sub></del> and not sub~</p>
+            <p><sub>sub and <del>sub delete</del></sub></p>
+            <p><del>delete and <sub>sub delete</sub></del></p>
+            <p><sub>sub <del>sub delete</del> sub</sub></p>
+            <p><del><sub>sub and delete</sub> delete</del>: foo bar <del>delete</del></p>
+            <p><sub><del>sub and delete</del> sub</sub> foo bar <del>delete</del></p>
+            <p><sub>sub and <del>sub delete</del></sub> <del>delete</del></p>
+            <p><del>delete and <sub>sub delete</sub></del> <del>delete</del></p>
+            ''',
+            True
         )
 
 
@@ -241,18 +280,57 @@ def test_case_11(self):
             True
         )
 
-    def test_complex_sub_del_under(self):
-        """Test `~text ~~text~~~`."""
+    def test_complex_cases(self):
+        """Test some complex cases."""
 
         self.check_markdown(
-            R"~I'm\ sub.\ ~~I'm\ sub\ and\ delete.~~~",
-            "<p><sub>I'm sub. <del>I'm sub and delete.</del></sub></p>"
-        )
+            R'''
+            ~~~I'm\ delete\ and\ sub~ I am just delete.~~
 
-    def test_complex_del_sub_under(self):
-        """Test `~~text ~text~~~`."""
+            ~~~I'm\ delete\ and\ sub!~~\ I\ am\ just\ sub.~
 
-        self.check_markdown(
-            R"~~I'm delete. ~I'm\ sub\ and\ delete.~~~",
-            "<p><del>I'm delete. <sub>I'm sub and delete.</sub></del></p>"
+            ~sub\ and\ ~~sub\ delete~~~ and ~sub~
+
+            ~~delete and ~sub\ delete~~~ and ~sub~
+
+            ~~~I'm\ sub\ and\ delete~ I am just delete.~~ ~sub~
+
+            ~~~I'm\ delete\ and\ sub!~~\ I\ am\ just\ sub.~ ~sub~
+
+            ~sub\ and\ ~~sub\ delete~~~ and not sub~
+
+            ~~delete and ~sub\ delete~~~ and not sub~
+
+            ~sub\ and\ ~~sub\ delete~~~
+
+            ~~delete and ~sub\ delete~~~
+
+            ~sub\ ~~sub\ delete~~\ sub~
+
+            ~~~sub\ and\ delete~ delete~~: foo bar ~~delete~~
+
+            ~~~sub\ and\ delete~~\ sub~ foo bar ~~delete~~
+
+            ~sub\ and\ ~~sub\ delete~~~ ~~delete~~
+
+            ~~delete and ~sub\ delete~~~ ~~delete~~
+            ''',
+            '''
+            <p><del><sub>I'm delete and sub</sub> I am just delete.</del></p>
+            <p><sub><del>I'm delete and sub!</del> I am just sub.</sub></p>
+            <p><sub>sub and <del>sub delete</del></sub> and <sub>sub</sub></p>
+            <p><del>delete and <sub>sub delete</sub></del> and <sub>sub</sub></p>
+            <p><del><sub>I'm sub and delete</sub> I am just delete.</del> <sub>sub</sub></p>
+            <p><sub><del>I'm delete and sub!</del> I am just sub.</sub> <sub>sub</sub></p>
+            <p><sub>sub and <del>sub delete</del></sub> and not sub~</p>
+            <p><del>delete and <sub>sub delete</sub></del> and not sub~</p>
+            <p><sub>sub and <del>sub delete</del></sub></p>
+            <p><del>delete and <sub>sub delete</sub></del></p>
+            <p><sub>sub <del>sub delete</del> sub</sub></p>
+            <p><del><sub>sub and delete</sub> delete</del>: foo bar <del>delete</del></p>
+            <p><sub><del>sub and delete</del> sub</sub> foo bar <del>delete</del></p>
+            <p><sub>sub and <del>sub delete</del></sub> <del>delete</del></p>
+            <p><del>delete and <sub>sub delete</sub></del> <del>delete</del></p>
+            ''',
+            True
         )