diff --git a/.changeset/stale-impalas-visit.md b/.changeset/stale-impalas-visit.md
new file mode 100644
index 00000000..06c542de
--- /dev/null
+++ b/.changeset/stale-impalas-visit.md
@@ -0,0 +1,5 @@
+---
+"htmljs-parser": patch
+---
+
+Fix regression where the parser would continue unary keyword expressions even if the keyword was inside a word boundary. Eg `
` would cause the parser to see the expression as `thing_` and `new x`.
diff --git a/src/__tests__/fixtures/attr-complex-unary/__snapshots__/attr-complex-unary.expected.txt b/src/__tests__/fixtures/attr-complex-unary/__snapshots__/attr-complex-unary.expected.txt
new file mode 100644
index 00000000..75c9de49
--- /dev/null
+++ b/src/__tests__/fixtures/attr-complex-unary/__snapshots__/attr-complex-unary.expected.txt
@@ -0,0 +1,80 @@
+1╭─ tag a = class b {}
+ │ │ │ │ ╰─ attrValue.value "class b {}"
+ │ │ │ ╰─ attrValue "= class b {}"
+ │ │ ╰─ attrName
+ ╰─ ╰─ tagName "tag"
+2╭─
+ ╰─ ╰─ openTagEnd
+3╭─ tag a = class, b
+ │ │ │ │ │ ╰─ attrName
+ │ │ │ │ ╰─ attrValue.value "class"
+ │ │ │ ╰─ attrValue "= class"
+ │ │ ╰─ attrName
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ tagName "tag"
+4╭─
+ ╰─ ╰─ openTagEnd
+5╭─
+ │ ││ │ │ │ ││ │ ╰─ closeTagEnd(tag)
+ │ ││ │ │ │ ││ ╰─ closeTagName "tag"
+ │ ││ │ │ │ │╰─ closeTagStart ""
+ │ ││ │ │ │ ╰─ openTagEnd
+ │ ││ │ │ ╰─ attrValue.value "class"
+ │ ││ │ ╰─ attrValue "= class"
+ │ ││ ╰─ attrName
+ │ │╰─ tagName "tag"
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ openTagStart
+6├─
+7╭─
+ │ ││ │ │ │ ╰─ openTagEnd:selfClosed "/>"
+ │ ││ │ │ ╰─ attrValue.value "class"
+ │ ││ │ ╰─ attrValue "= class"
+ │ ││ ╰─ attrName
+ │ │╰─ tagName "tag"
+ ╰─ ╰─ openTagStart
+8├─
+9╭─ tag a = classthing b
+ │ │ │ │ │ ╰─ attrName
+ │ │ │ │ ╰─ attrValue.value "classthing"
+ │ │ │ ╰─ attrValue "= classthing"
+ │ │ ╰─ attrName
+ ╰─ ╰─ tagName "tag"
+10╭─
+ ╰─ ╰─ openTagEnd
+11╭─ tag a = testclass b
+ │ │ │ │ │ ╰─ attrName
+ │ │ │ │ ╰─ attrValue.value "testclass"
+ │ │ │ ╰─ attrValue "= testclass"
+ │ │ ╰─ attrName
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ tagName "tag"
+12╭─
+ ╰─ ╰─ openTagEnd
+13╭─ tag a = test_class b
+ │ │ │ │ │ ╰─ attrName
+ │ │ │ │ ╰─ attrValue.value "test_class"
+ │ │ │ ╰─ attrValue "= test_class"
+ │ │ ╰─ attrName
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ tagName "tag"
+14╭─
+ ╰─ ╰─ openTagEnd
+15╭─ tag a = test$class b
+ │ │ │ │ │ ╰─ attrName
+ │ │ │ │ ╰─ attrValue.value "test$class"
+ │ │ │ ╰─ attrValue "= test$class"
+ │ │ ╰─ attrName
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ tagName "tag"
+16╭─
+ ╰─ ╰─ openTagEnd
+17╭─ tag a = test+class b
+ │ │ │ │ ╰─ attrValue.value "test+class b"
+ │ │ │ ╰─ attrValue "= test+class b"
+ │ │ ╰─ attrName
+ │ ├─ closeTagEnd(tag)
+ ╰─ ╰─ tagName "tag"
+18╭─
+ │ ├─ openTagEnd
+ ╰─ ╰─ closeTagEnd(tag)
\ No newline at end of file
diff --git a/src/__tests__/fixtures/attr-complex-unary/input.marko b/src/__tests__/fixtures/attr-complex-unary/input.marko
new file mode 100644
index 00000000..e9e73b2e
--- /dev/null
+++ b/src/__tests__/fixtures/attr-complex-unary/input.marko
@@ -0,0 +1,17 @@
+tag a = class b {}
+
+tag a = class, b
+
+
+
+
+
+tag a = classthing b
+
+tag a = testclass b
+
+tag a = test_class b
+
+tag a = test$class b
+
+tag a = test+class b
diff --git a/src/states/EXPRESSION.ts b/src/states/EXPRESSION.ts
index d1954cbf..a0e91bfa 100644
--- a/src/states/EXPRESSION.ts
+++ b/src/states/EXPRESSION.ts
@@ -296,7 +296,8 @@ function lookBehindForOperator(data: string, pos: number): number {
for (const keyword of unaryKeywords) {
const keywordPos = lookBehindFor(data, curPos, keyword);
if (keywordPos !== -1) {
- return data.charCodeAt(keywordPos - 1) === CODE.PERIOD
+ const prevCode = data.charCodeAt(keywordPos - 1);
+ return prevCode === CODE.PERIOD || isWordCode(prevCode)
? -1
: keywordPos;
}