Skip to content

Conversation

@JoanJaraBosch
Copy link

@JoanJaraBosch JoanJaraBosch commented Oct 2, 2025

Summary

Describe the change and its motivation.

Checklist

  • Tests pass: make verify or golearn verify <slug>
  • Docs updated (README/CONTRIBUTING) if needed
  • No large new dependencies

Screenshots / Output (if CLI UX)

Paste before/after where helpful.

Related issues

Fixes #

Summary by CodeRabbit

  • New Features

    • Added a new "Regular Expressions" exercise to the catalog (visible under Concepts/Projects and in the 109_epoch project) with starter template and hints for practicing regex matching.
    • Included a reference solution to demonstrate expected behavior.
  • Tests

    • Added a test suite that validates matching behavior for the new Regular Expressions exercise.

@coderabbitai
Copy link

coderabbitai bot commented Oct 2, 2025

Walkthrough

Adds a new "Regular Expressions" exercise: catalog entries, template (stub) and tests, plus a reference solution in Go exposing MatchRegex(pattern, input string) bool using the regexp package.

Changes

Cohort / File(s) Summary of Changes
Catalog update
internal/exercises/catalog.yaml
Added exercise entry with slug regular-expressions under concepts/projects and duplicated under the 109_epoch project block.
Templates: exercise code and tests
internal/exercises/templates/115_regular_expressions/regular_expressions.go, internal/exercises/templates/115_regular_expressions/regular_expressions_test.go
Introduced template MatchRegex(pattern string, input string) bool (currently a stub returning false) and added table-driven tests exercising regex matching cases.
Solutions: reference implementation
internal/exercises/solutions/115_regular_expressions/regular_expressions.go
Added solution implementing MatchRegex(pattern, input string) bool: compiles the pattern (returns false on compile error) and returns whether the input matches the compiled regex.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Tester as Test Runner
  participant Impl as MatchRegex
  participant Std as regexp (stdlib)

  Tester->>Impl: MatchRegex(pattern, input)
  Impl->>Std: Compile(pattern)
  alt compile error
    Std-->>Impl: error
    Impl-->>Tester: false
  else compiled
    Std-->>Impl: *Regexp
    Impl->>Std: MatchString(input)
    Std-->>Impl: bool
    Impl-->>Tester: result
  end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

patch

Suggested reviewers

  • zhravan

Poem

In fields of dots and stars I play,
I hop through patterns, night and day.
Compile the weave, then test the string—
A match! the bells of victory ring.
— Rabbit regexer, swift and gay 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The title uses an abbreviation and awkward phrasing that makes it unclear whether it refers to adding a new exercise, implementing regex support, or updating an existing exercise. It partially reflects the addition of a regular expressions exercise but lacks specificity and concise wording. A clearer description would help reviewers quickly grasp the primary change. Please update the title to clearly and concisely reflect the main change, for example “feat: add regular expressions exercise” or “feat: introduce regex matching exercise.”
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 820abd3 and 20a6a66.

📒 Files selected for processing (1)
  • internal/exercises/catalog.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/exercises/catalog.yaml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
internal/exercises/catalog.yaml (1)

205-213: Consider adding difficulty and topics metadata.

Unlike the 109_epoch exercise above (lines 196-203), this entry lacks difficulty and topics fields. Adding them would improve consistency and help learners filter exercises.

Example addition:

 - slug: regular-expressions
   title: Regular Expressions
+  difficulty: beginner
+  topics: ["regexp", "pattern matching"]
   test_regex: ".*"
   hints:
internal/exercises/templates/regular-expressions/regular-expressions_test.go (1)

5-26: LGTM! Consider adding tests for invalid patterns.

The test structure is idiomatic and covers typical regex use cases. The test cases are appropriate for a beginner exercise.

However, the current implementation stub in internal/exercises/templates/regular-expressions/regular-expressions.go (line 10) does not return an error. If learners are expected to handle invalid patterns (e.g., unclosed brackets like "[0-9"), consider either:

  1. Adding test cases for invalid patterns and expecting a specific behavior (e.g., returning false or panicking), or
  2. Updating the function signature to return (bool, error) and adding error-handling tests.

Example test case if sticking with bool return:

{"[0-9", "123", false}, // invalid pattern, expect false or panic
internal/exercises/templates/regular-expressions/regular-expressions.go (1)

9-13: Enhance TODO comment to guide error handling.

The function signature returns only bool, so learners using regexp.MustCompile on invalid patterns will face panics. Enhance the TODO to suggest using regexp.Compile and checking errors, or clarify that MustCompile is acceptable for trusted patterns.

Apply this diff:

 // MatchRegex returns true if the input matches the pattern, false otherwise.
 func MatchRegex(pattern, input string) bool {
-	// TODO: implement this function
+	// TODO: implement this function using regexp.Compile and check for errors,
+	// or use regexp.MustCompile if you are certain the pattern is valid.
 	return false
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94fd4b3 and 224e4af.

📒 Files selected for processing (3)
  • internal/exercises/catalog.yaml (1 hunks)
  • internal/exercises/templates/regular-expressions/regular-expressions.go (1 hunks)
  • internal/exercises/templates/regular-expressions/regular-expressions_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
internal/exercises/templates/regular-expressions/regular-expressions_test.go (1)
internal/exercises/templates/regular-expressions/regular-expressions.go (1)
  • MatchRegex (10-13)

Copy link
Owner

@zhravan zhravan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM, can you please add solutions to it as well?

@JoanJaraBosch JoanJaraBosch requested a review from zhravan October 2, 2025 12:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal/exercises/solution/regular-expressions_solution.go (2)

9-12: Consider explicit error handling for invalid patterns.

Returning false for both compilation errors and non-matches conflates two distinct failure modes. Callers cannot distinguish "invalid pattern" from "valid pattern, no match." For an exercise solution, consider whether teaching explicit error propagation would be more valuable.

If patterns are expected to always be valid (e.g., hardcoded in tests), use regexp.MustCompile to panic on invalid patterns:

 func MatchRegex(pattern, input string) bool {
-	re, err := regexp.Compile(pattern)
-	if err != nil {
-		return false
-	}
+	re := regexp.MustCompile(pattern)
 	return re.MatchString(input)
 }

Alternatively, if invalid patterns should be handled gracefully, return an error to the caller:

-func MatchRegex(pattern, input string) bool {
+func MatchRegex(pattern, input string) (bool, error) {
 	re, err := regexp.Compile(pattern)
 	if err != nil {
-		return false
+		return false, err
 	}
-	return re.MatchString(input)
+	return re.MatchString(input), nil
 }

9-13: Performance: Pattern compilation on every call.

regexp.Compile is invoked on every call, which can be expensive for repeated matches with the same pattern. For production code, consider compiling once and reusing the regex. However, if this is intentional for the exercise (to teach basic regex usage), this is acceptable.

If performance matters and patterns are reused, consider caching compiled regexes or accepting a pre-compiled *regexp.Regexp:

// Example: Accept pre-compiled regex
func MatchRegex(re *regexp.Regexp, input string) bool {
	return re.MatchString(input)
}

Or use regexp.MatchString for simple one-off matches:

 func MatchRegex(pattern, input string) bool {
-	re, err := regexp.Compile(pattern)
-	if err != nil {
-		return false
-	}
-	return re.MatchString(input)
+	matched, err := regexp.MatchString(pattern, input)
+	if err != nil {
+		return false
+	}
+	return matched
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f3ef477 and 4cc01fb.

📒 Files selected for processing (2)
  • internal/exercises/catalog.yaml (1 hunks)
  • internal/exercises/solution/regular-expressions_solution.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/exercises/catalog.yaml

@zhravan
Copy link
Owner

zhravan commented Oct 2, 2025

@JoanJaraBosch : Can you please follow the naming convention as per the files please?

@JoanJaraBosch
Copy link
Author

2

I think now it is correct

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal/exercises/templates/regular_expressions/regular_expressions_test.go (1)

5-26: LGTM! Consider adding edge case coverage.

The test structure follows Go table-driven test conventions correctly. The current test cases cover anchors, character classes, and alternation patterns effectively.

For more comprehensive coverage, consider adding tests for:

  • Empty pattern and empty input
  • Invalid regex patterns (to verify error handling)
  • Quantifiers: *, +, ?, {n,m}
  • Escaped special characters: \., \d, \w
  • Boundary matchers: \b

Additionally, using subtests with t.Run() would improve test isolation and provide clearer failure messages:

-	for _, tt := range tests {
+	for _, tt := range tests {
+		t.Run(tt.pattern+"_"+tt.input, func(t *testing.T) {
 		got := MatchRegex(tt.pattern, tt.input)
 		if got != tt.want {
 			t.Errorf("MatchRegex(%q, %q) = %v; want %v", tt.pattern, tt.input, got, tt.want)
 		}
+		})
 	}
internal/exercises/solutions/regular_expressions/regular_expressions_solution.go (1)

7-14: LGTM! Implementation is correct.

The solution correctly compiles the regex pattern and matches it against the input. Returning false on compilation errors provides graceful handling for invalid patterns, which aligns with the boolean return signature.

For a more concise implementation, you could use regexp.MatchString directly, which handles compilation internally:

-func MatchRegex(pattern, input string) bool {
-	re, err := regexp.Compile(pattern)
-	if err != nil {
-		return false
-	}
-	return re.MatchString(input)
-}
+func MatchRegex(pattern, input string) bool {
+	matched, _ := regexp.MatchString(pattern, input)
+	return matched
+}

However, the current approach is more explicit and educational for learners, showing the two-step process of compilation and matching.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b156227 and e9aadce.

📒 Files selected for processing (3)
  • internal/exercises/solutions/regular_expressions/regular_expressions_solution.go (1 hunks)
  • internal/exercises/templates/regular_expressions/regular_expressions.go (1 hunks)
  • internal/exercises/templates/regular_expressions/regular_expressions_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
internal/exercises/templates/regular_expressions/regular_expressions.go (1)
internal/exercises/solutions/regular_expressions/regular_expressions_solution.go (1)
  • MatchRegex (8-14)
internal/exercises/solutions/regular_expressions/regular_expressions_solution.go (1)
internal/exercises/templates/regular_expressions/regular_expressions.go (1)
  • MatchRegex (10-13)
internal/exercises/templates/regular_expressions/regular_expressions_test.go (2)
internal/exercises/solutions/regular_expressions/regular_expressions_solution.go (1)
  • MatchRegex (8-14)
internal/exercises/templates/regular_expressions/regular_expressions.go (1)
  • MatchRegex (10-13)
🔇 Additional comments (1)
internal/exercises/templates/regular_expressions/regular_expressions.go (1)

1-13: LGTM! Template structure is appropriate.

The exercise template correctly provides:

  • Clear file and package documentation
  • The function signature matching the solution
  • A TODO marker for learners to implement
  • Necessary imports already in place
  • A safe default return value

This scaffolding gives learners the right starting point without revealing the solution.

Note: The PR comment from @zhravan mentions following naming conventions. The current file uses regular_expressions.go (snake_case), which is standard Go convention for filenames. If there's a specific project naming convention, please clarify.

@zhravan zhravan changed the title templates created feat: add regular expr on exercise Oct 5, 2025
@zhravan zhravan changed the title feat: add regular expr on exercise feat: regular expr on exercise Oct 5, 2025
Copy link
Owner

@zhravan zhravan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rest lgtm, one minor change required, lmk once that is done.

Thank you for considering contributing to the project.

@JoanJaraBosch JoanJaraBosch requested a review from zhravan October 5, 2025 20:03
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
internal/exercises/templates/115_regular_expressions/regular_expressions_test.go (2)

7-28: LGTM! Consider using subtests for better test output.

The test implementation is correct and covers basic regex functionality well. The table-driven approach follows Go best practices.

Consider refactoring to use subtests with t.Run() for clearer output when tests fail:

 func TestMatchRegex(t *testing.T) {
 	tests := []struct {
+		name    string
 		pattern string
 		input   string
 		want    bool
 	}{
-		{"^a.*z$", "abcz", true},
-		{"^a.*z$", "abz", true},
-		{"^a.*z$", "abc", false},
-		{"[0-9]+", "123", true},
-		{"[0-9]+", "abc", false},
-		{"hello|world", "hello", true},
-		{"hello|world", "world", true},
-		{"hello|world", "hi", false},
+		{"anchor with wildcard match", "^a.*z$", "abcz", true},
+		{"anchor with wildcard shorter", "^a.*z$", "abz", true},
+		{"anchor with wildcard no match", "^a.*z$", "abc", false},
+		{"digit class match", "[0-9]+", "123", true},
+		{"digit class no match", "[0-9]+", "abc", false},
+		{"alternation first option", "hello|world", "hello", true},
+		{"alternation second option", "hello|world", "world", true},
+		{"alternation no match", "hello|world", "hi", false},
 	}
 	for _, tt := range tests {
-		got := MatchRegex(tt.pattern, tt.input)
-		if got != tt.want {
-			t.Errorf("MatchRegex(%q, %q) = %v; want %v", tt.pattern, tt.input, got, tt.want)
-		}
+		t.Run(tt.name, func(t *testing.T) {
+			got := MatchRegex(tt.pattern, tt.input)
+			if got != tt.want {
+				t.Errorf("MatchRegex(%q, %q) = %v; want %v", tt.pattern, tt.input, got, tt.want)
+			}
+		})
 	}
 }

13-21: Consider adding edge case tests.

The current test cases cover common regex patterns well. You might want to add tests for:

  • Invalid regex patterns (e.g., "[", "(?P<", "*abc")
  • Empty strings ("", "", "a+", "")
  • Special characters that need escaping ("\.", "hello.world")

Example additions:

{"invalid pattern", "[", "test", false},
{"empty pattern and input", "", "", true},
{"empty input with pattern", "a+", "", false},
{"escaped special char", `\.`, ".", true},
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72a9c45 and 820abd3.

📒 Files selected for processing (3)
  • internal/exercises/solutions/115_regular_expressions/regular_expressions.go (1 hunks)
  • internal/exercises/templates/115_regular_expressions/regular_expressions.go (1 hunks)
  • internal/exercises/templates/115_regular_expressions/regular_expressions_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
internal/exercises/templates/115_regular_expressions/regular_expressions.go (1)
internal/exercises/solutions/115_regular_expressions/regular_expressions.go (1)
  • MatchRegex (10-16)
internal/exercises/solutions/115_regular_expressions/regular_expressions.go (1)
internal/exercises/templates/115_regular_expressions/regular_expressions.go (1)
  • MatchRegex (12-15)
internal/exercises/templates/115_regular_expressions/regular_expressions_test.go (2)
internal/exercises/solutions/115_regular_expressions/regular_expressions.go (1)
  • MatchRegex (10-16)
internal/exercises/templates/115_regular_expressions/regular_expressions.go (1)
  • MatchRegex (12-15)
🔇 Additional comments (2)
internal/exercises/solutions/115_regular_expressions/regular_expressions.go (1)

9-16: LGTM! Solution is correct and appropriate for educational context.

The implementation correctly:

  • Compiles the regex pattern using regexp.Compile
  • Handles compilation errors by returning false
  • Uses MatchString to test if the input matches the pattern

This straightforward approach is well-suited for an educational exercise, making it easy for learners to understand the basic regex workflow.

internal/exercises/templates/115_regular_expressions/regular_expressions.go (1)

11-15: LGTM! Template provides clear scaffold for learners.

The function stub is well-structured:

  • Clear function signature matching the solution
  • TODO comment guides learners on what to implement
  • regexp package already imported for convenience
  • Placeholder return value allows compilation

This is an appropriate template for an educational exercise.

@JoanJaraBosch
Copy link
Author

done @zhravan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants