diff --git a/pkg/analyzer/commit_analyzer.go b/pkg/analyzer/commit_analyzer.go
index 04a294b1b350dd3a30bc956688c9fca27662a461..76cecc55608703969422549a930f4afabc7cdbc7 100644
--- a/pkg/analyzer/commit_analyzer.go
+++ b/pkg/analyzer/commit_analyzer.go
@@ -9,7 +9,7 @@ import (
 
 var (
 	CAVERSION              = "dev"
-	commitPattern          = regexp.MustCompile(`^(\w*)(?:\((.*)\))?(\!)?\: (.*)$`)
+	commitPattern          = regexp.MustCompile(`^([^\s\(\!]+)(?:\(([^\)]*)\))?(\!)?\: (.*)$`)
 	breakingPattern        = regexp.MustCompile("BREAKING CHANGES?")
 	mentionedIssuesPattern = regexp.MustCompile(`#(\d+)`)
 	mentionedUsersPattern  = regexp.MustCompile(`(?i)@([a-z\d]([a-z\d]|-[a-z\d])+)`)
diff --git a/pkg/analyzer/commit_analyzer_test.go b/pkg/analyzer/commit_analyzer_test.go
index d08276fb1728ea02dacd237f3bff1aab70aec4f3..14c356f24cec71c4abb937ec6dada2d9bdca7301 100644
--- a/pkg/analyzer/commit_analyzer_test.go
+++ b/pkg/analyzer/commit_analyzer_test.go
@@ -112,3 +112,69 @@ func TestDefaultAnalyzer(t *testing.T) {
 		})
 	}
 }
+
+func TestCommitPattern(t *testing.T) {
+	testCases := []struct {
+		rawMessage string
+		wanted     []string
+	}{
+		{
+			rawMessage: "feat: new feature",
+			wanted:     []string{"feat", "", "", "new feature"},
+		},
+		{
+			rawMessage: "feat!: new feature",
+			wanted:     []string{"feat", "", "!", "new feature"},
+		},
+		{
+			rawMessage: "feat(api): new feature",
+			wanted:     []string{"feat", "api", "", "new feature"},
+		},
+		{
+			rawMessage: "feat(api): a(b): c:",
+			wanted:     []string{"feat", "api", "", "a(b): c:"},
+		},
+		{
+			rawMessage: "feat(new cool-api): feature",
+			wanted:     []string{"feat", "new cool-api", "", "feature"},
+		},
+		{
+			rawMessage: "feat(😅): cool",
+			wanted:     []string{"feat", "😅", "", "cool"},
+		},
+		{
+			rawMessage: "this-is-also(valid): cool",
+			wanted:     []string{"this-is-also", "valid", "", "cool"},
+		},
+		{
+			rawMessage: "🚀(🦄): emojis!",
+			wanted:     []string{"🚀", "🦄", "", "emojis!"},
+		},
+		// invalid messages
+		{
+			rawMessage: "feat (new api): feature",
+			wanted:     nil,
+		},
+		{
+			rawMessage: "feat((x)): test",
+			wanted:     nil,
+		},
+		{
+			rawMessage: "feat:test",
+			wanted:     nil,
+		},
+	}
+	for _, tc := range testCases {
+		t.Run(fmt.Sprintf("CommitPattern: %s", tc.rawMessage), func(t *testing.T) {
+			rawMessageLines := strings.Split(tc.rawMessage, "\n")
+			found := commitPattern.FindAllStringSubmatch(rawMessageLines[0], -1)
+			if len(tc.wanted) == 0 {
+				require.Len(t, found, 0)
+				return
+			}
+			require.Len(t, found, 1)
+			require.Len(t, found[0], 5)
+			require.Equal(t, tc.wanted, found[0][1:])
+		})
+	}
+}