diff --git a/lib/command/dryRun.js b/lib/command/dryRun.js
index 0de23df4f..75734185f 100644
--- a/lib/command/dryRun.js
+++ b/lib/command/dryRun.js
@@ -7,7 +7,7 @@ const store = require('../store')
 const Container = require('../container')
 
 module.exports = async function (test, options) {
-  if (options.grep) process.env.grep = options.grep.toLowerCase()
+  if (options.grep) process.env.grep = options.grep
   const configFile = options.config
   let codecept
 
@@ -60,35 +60,40 @@ function printTests(files) {
   let numOfTests = 0
   let numOfSuites = 0
   let outputString = ''
-  const filterBy = process.env.grep ? process.env.grep.toLowerCase() : undefined
+  const filterBy = process.env.grep
 
+  let filterRegex
   if (filterBy) {
-    for (const suite of mocha.suite.suites) {
-      const currentSuite = suite.title
-      if (suite.title.toLowerCase().includes(filterBy)) {
-        outputString += `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')} -- ${mocha.suite.suites.length} tests\n`
-        numOfSuites++
-      }
-
-      for (test of suite.tests) {
-        if (test.title.toLowerCase().includes(filterBy)) {
-          numOfTests++
-          outputString += `${colors.white.bold(test.parent.title)} -- ${output.styles.log(test.parent.file || '')} -- ${mocha.suite.suites.length} tests\n`
-          outputString += `  ${output.styles.scenario(figures.checkboxOff)} ${test.title}\n`
-        }
-      }
+    try {
+      filterRegex = new RegExp(filterBy, 'i') // Case-insensitive matching
+    } catch (err) {
+      console.error(`Invalid grep pattern: ${filterBy}`)
+      process.exit(1)
     }
-    numOfSuites = countSuites(outputString)
-  } else {
-    for (const suite of mocha.suite.suites) {
-      output.print(
-        `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')} -- ${mocha.suite.suites.length} tests`,
-      )
+  }
+
+  for (const suite of mocha.suite.suites) {
+    const suiteMatches = filterRegex ? filterRegex.test(suite.title) : true
+    let suiteHasMatchingTests = false
+
+    if (suiteMatches) {
+      outputString += `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')}\n`
+      suiteHasMatchingTests = true
       numOfSuites++
+    }
+
+    for (const test of suite.tests) {
+      const testMatches = filterRegex ? filterRegex.test(test.title) : true
+
+      if (testMatches) {
+        if (!suiteMatches && !suiteHasMatchingTests) {
+          outputString += `${colors.white.bold(suite.title)} -- ${output.styles.log(suite.file || '')}\n`
+          suiteHasMatchingTests = true
+          numOfSuites++
+        }
 
-      for (test of suite.tests) {
         numOfTests++
-        output.print(`  ${output.styles.scenario(figures.checkboxOff)} ${test.title}`)
+        outputString += `  ${output.styles.scenario(figures.checkboxOff)} ${test.title}\n`
       }
     }
   }
@@ -108,15 +113,5 @@ function printFooter() {
 function removeDuplicates(inputString) {
   const array = inputString.split('\n')
   const uniqueLines = [...new Set(array)]
-  const resultString = uniqueLines.join('\n')
-
-  return resultString
-}
-
-function countSuites(inputString) {
-  const array = inputString.split('\n')
-
-  const uniqueLines = [...new Set(array)]
-  const res = uniqueLines.filter((item) => item.includes('-- '))
-  return res.length
+  return uniqueLines.join('\n')
 }
diff --git a/test/runner/dry_run_test.js b/test/runner/dry_run_test.js
index 444de2fde..851c7fc49 100644
--- a/test/runner/dry_run_test.js
+++ b/test/runner/dry_run_test.js
@@ -117,6 +117,25 @@ describe('dry-run command', () => {
     })
   })
 
+  it('should run feature files with regex grep', (done) => {
+    exec(codecept_run_config('codecept.bdd.js') + ' --steps --grep "(?=.*Checkout process)"', (err, stdout) => {
+      //eslint-disable-line
+      expect(stdout).toContain('Checkout process') // feature
+      expect(stdout).toContain('-- before checkout --')
+      expect(stdout).toContain('-- after checkout --')
+      // expect(stdout).toContain('In order to buy products'); // test name
+      expect(stdout).toContain('Given I have product with $600 price')
+      expect(stdout).toContain('And I have product with $1000 price')
+      expect(stdout).toContain('Then I should see that total number of products is 2')
+      expect(stdout).toContain('And my order amount is $1600')
+      expect(stdout).not.toContain('I add item 600') // 'Given' actor's non-gherkin step check
+      expect(stdout).not.toContain('I see sum 1600') // 'And' actor's non-gherkin step check
+      expect(stdout).toContain('No tests were executed')
+      expect(err).toBeFalsy()
+      done()
+    })
+  })
+
   it('should print substeps in debug mode', (done) => {
     exec(codecept_run_config('codecept.bdd.js') + ' --debug --grep "Checkout process @important"', (err, stdout) => {
       //eslint-disable-line