diff --git a/lib/modules/manager/pep621/extract.spec.ts b/lib/modules/manager/pep621/extract.spec.ts
index 37bd318ea6e5507192e5efda45a77344e245a252..5eec2566337b590176caeb10394a2b7163bf5f50 100644
--- a/lib/modules/manager/pep621/extract.spec.ts
+++ b/lib/modules/manager/pep621/extract.spec.ts
@@ -605,5 +605,25 @@ describe('modules/manager/pep621/extract', () => {
         ],
       });
     });
+
+    it('should resolve dependencies with template', async () => {
+      const content = codeBlock`
+            [project]
+            name = "{{ name }}"
+            dynamic = ["version"]
+            requires-python = ">=3.7"
+            license = {text = "MIT"}
+            {# comment #}
+            dependencies = [
+              "blinker",
+              {% if foo %}
+              "packaging>=20.9,!=22.0",
+              {% endif %}
+            ]
+            readme = "README.md"
+          `;
+      const res = await extractPackageFile(content, 'pyproject.toml');
+      expect(res?.deps).toHaveLength(2);
+    });
   });
 });
diff --git a/lib/modules/manager/pep621/utils.ts b/lib/modules/manager/pep621/utils.ts
index 6df1b79ae4e0187c5fbad0bd19a0a04b92f7c072..a53f9530805cae81204785e7b44b15cdf06870a5 100644
--- a/lib/modules/manager/pep621/utils.ts
+++ b/lib/modules/manager/pep621/utils.ts
@@ -1,6 +1,7 @@
 import is from '@sindresorhus/is';
 import { logger } from '../../../logger';
 import { regEx } from '../../../util/regex';
+import { stripTemplates } from '../../../util/string';
 import { parse as parseToml } from '../../../util/toml';
 import { PypiDatasource } from '../../datasource/pypi';
 import { normalizePythonDepName } from '../../datasource/pypi/common';
@@ -136,7 +137,7 @@ export function parsePyProject(
   content: string,
 ): PyProject | null {
   try {
-    const jsonMap = parseToml(content);
+    const jsonMap = parseToml(stripTemplates(content));
     return PyProjectSchema.parse(jsonMap);
   } catch (err) {
     logger.debug(
diff --git a/lib/modules/manager/poetry/artifacts.ts b/lib/modules/manager/poetry/artifacts.ts
index fd495a25c98931d68d75e7ab9159c3c2d4c2df0f..d75a66934438a3a809c99a1cbebfe5e60f1a4f07 100644
--- a/lib/modules/manager/poetry/artifacts.ts
+++ b/lib/modules/manager/poetry/artifacts.ts
@@ -16,6 +16,7 @@ import { getGitEnvironmentVariables } from '../../../util/git/auth';
 import { find } from '../../../util/host-rules';
 import { regEx } from '../../../util/regex';
 import { Result } from '../../../util/result';
+import { stripTemplates } from '../../../util/string';
 import { parse as parseToml } from '../../../util/toml';
 import { parseUrl } from '../../../util/url';
 import { PypiDatasource } from '../../datasource/pypi';
@@ -97,7 +98,7 @@ export function getPoetryRequirement(
 function getPoetrySources(content: string, fileName: string): PoetrySource[] {
   let pyprojectFile: PoetryFile;
   try {
-    pyprojectFile = parseToml(content) as PoetryFile;
+    pyprojectFile = parseToml(stripTemplates(content)) as PoetryFile;
   } catch (err) {
     logger.debug({ err }, 'Error parsing pyproject.toml file');
     return [];
diff --git a/lib/modules/manager/poetry/extract.spec.ts b/lib/modules/manager/poetry/extract.spec.ts
index 5801cd73c93e6b988f6c6da3d4ca1f076a957d55..ead38910d40e2538d9058bdc9f9a42698e5134cb 100644
--- a/lib/modules/manager/poetry/extract.spec.ts
+++ b/lib/modules/manager/poetry/extract.spec.ts
@@ -496,5 +496,22 @@ describe('modules/manager/poetry/extract', () => {
         ]);
       });
     });
+
+    it('parses package file with template', async () => {
+      const content = codeBlock`
+            [tool.poetry]
+            name = "{{ name }}"
+            {# comment #}
+            [tool.poetry.dependencies]
+            python = "^3.9"
+            {% if foo %}
+            dep1 = "^1.0.0"
+            {% endif %}
+          `;
+      const res = await extractPackageFile(content, filename);
+      expect(res?.deps).toHaveLength(2);
+      expect(res?.deps[0].depName).toBe('python');
+      expect(res?.deps[1].depName).toBe('dep1');
+    });
   });
 });
diff --git a/lib/modules/manager/poetry/extract.ts b/lib/modules/manager/poetry/extract.ts
index 60c49df062118baaf1e189eed8be28345facc166..71fb2f0049fe141c6fd08281b45992de2df052f9 100644
--- a/lib/modules/manager/poetry/extract.ts
+++ b/lib/modules/manager/poetry/extract.ts
@@ -7,6 +7,7 @@ import {
   readLocalFile,
 } from '../../../util/fs';
 import { Result } from '../../../util/result';
+import { stripTemplates } from '../../../util/string';
 import { GithubReleasesDatasource } from '../../datasource/github-releases';
 import type { PackageFileContent } from '../types';
 import { Lockfile, PoetrySchemaToml } from './schema';
@@ -17,7 +18,7 @@ export async function extractPackageFile(
 ): Promise<PackageFileContent | null> {
   logger.trace(`poetry.extractPackageFile(${packageFile})`);
   const { val: res, err } = Result.parse(
-    content,
+    stripTemplates(content),
     PoetrySchemaToml.transform(({ packageFileContent }) => packageFileContent),
   ).unwrap();
   if (err) {
diff --git a/lib/util/string.spec.ts b/lib/util/string.spec.ts
index 9df3c52ac209371c740da67975e60760c9f56251..dc34cd8f8047d11cc48cc65a5c767dc19a041889 100644
--- a/lib/util/string.spec.ts
+++ b/lib/util/string.spec.ts
@@ -1,4 +1,4 @@
-import { coerceString, looseEquals, replaceAt } from './string';
+import { coerceString, looseEquals, replaceAt, stripTemplates } from './string';
 
 describe('util/string', () => {
   describe('replaceAt', () => {
@@ -40,4 +40,34 @@ describe('util/string', () => {
     expect(coerceString(null)).toBe('');
     expect(coerceString(null, 'foo')).toBe('foo');
   });
+
+  describe('stripTemplates', () => {
+    test.each`
+      input                                                        | expected
+      ${'This is {% template %} text.'}                            | ${'This is  text.'}
+      ${'This is {%` template `%} text.'}                          | ${'This is  text.'}
+      ${'Calculate {{ sum }} of numbers.'}                         | ${'Calculate  of numbers.'}
+      ${'Calculate {{` sum `}} of numbers.'}                       | ${'Calculate  of numbers.'}
+      ${'Text with {# comment #} embedded comment.'}               | ${'Text with  embedded comment.'}
+      ${'Start {{ value }} middle {% code %} end {# note #}.'}     | ${'Start  middle  end .'}
+      ${'Nested {{ {% pattern %} }} test.'}                        | ${'Nested  test.'}
+      ${'Line before {%\n  multi-line\n  pattern\n%} line after.'} | ${'Line before  line after.'}
+      ${'Plain text with no patterns.'}                            | ${'Plain text with no patterns.'}
+      ${'Overlap {# comment {% nested %} #} test.'}                | ${'Overlap  test.'}
+      ${'Unmatched {% pattern missing end.'}                       | ${'Unmatched {% pattern missing end.'}
+      ${'Unmatched pattern missing start %}.'}                     | ${'Unmatched pattern missing start %}.'}
+      ${'{{ first }}{% second %}{# third #}Final text.'}           | ${'Final text.'}
+      ${'Empty patterns {% %}{{ }}{# #}.'}                         | ${'Empty patterns .'}
+      ${'{% start %} Middle text {# end #}'}                       | ${' Middle text '}
+      ${'{% a %}{{ b }}{# c #}'}                                   | ${''}
+      ${'{%` only `%}{{` patterns `}}{# here #}'}                  | ${''}
+      ${'Escaped \\{% not a pattern %\\} text.'}                   | ${'Escaped \\{% not a pattern %\\} text.'}
+      ${'Content with escaped \\{\\{ braces \\}\\}.'}              | ${'Content with escaped \\{\\{ braces \\}\\}.'}
+      ${'Unicode {{ 🚀🌟 }} characters.'}                          | ${'Unicode  characters.'}
+      ${'Special {{ $^.*+?()[]{}|\\ }} characters.'}               | ${'Special  characters.'}
+      ${'{% entire text %}'}                                       | ${''}
+    `('"$input" -> "$expected"', ({ input, expected }) => {
+      expect(stripTemplates(input)).toBe(expected);
+    });
+  });
 });
diff --git a/lib/util/string.ts b/lib/util/string.ts
index 4ad6797651b067d881a7a3f646461ca5dfb35496..451fd5091fe5cce5dfb80be3b93a22f1ceeeb79a 100644
--- a/lib/util/string.ts
+++ b/lib/util/string.ts
@@ -90,3 +90,81 @@ export function coerceString(
 ): string {
   return val ?? def ?? '';
 }
+
+/**
+ * Remove templates from string.
+ *
+ * This is more performant version of this code:
+ *
+ * ```
+ *   content
+ *     .replaceAll(regEx(/{{`.+?`}}/gs), '')
+ *     .replaceAll(regEx(/{{.+?}}/gs), '')
+ *     .replaceAll(regEx(/{%`.+?`%}/gs), '')
+ *     .replaceAll(regEx(/{%.+?%}/gs), '')
+ *     .replaceAll(regEx(/{#.+?#}/gs), '')
+ * ```
+ */
+export function stripTemplates(content: string): string {
+  const result: string[] = [];
+
+  const len = content.length;
+  let idx = 0;
+  let lastPos = 0; // Tracks the start index of the next chunk to push
+  while (idx < len) {
+    if (content[idx] === '{' && idx + 1 < len) {
+      let closing: string | undefined;
+      let skipLength = 0;
+
+      if (content[idx + 1] === '%') {
+        if (idx + 2 < len && content[idx + 2] === '`') {
+          // Handle `{%` ... `%}`
+          closing = '`%}';
+          skipLength = 3;
+        } else {
+          // Handle `{% ... %}`
+          closing = '%}';
+          skipLength = 2;
+        }
+      } else if (content[idx + 1] === '{') {
+        if (idx + 2 < len && content[idx + 2] === '`') {
+          // Handle `{{` ... `}}`
+          closing = '`}}';
+          skipLength = 3;
+        } else {
+          // Handle `{{ ... }}`
+          closing = '}}';
+          skipLength = 2;
+        }
+      } else if (content[idx + 1] === '#') {
+        // Handle `{# ... #}`
+        closing = '#}';
+        skipLength = 2;
+      }
+
+      if (closing) {
+        const end = content.indexOf(closing, idx + skipLength);
+        if (end !== -1) {
+          // Append the content before the pattern
+          if (idx > lastPos) {
+            result.push(content.slice(lastPos, idx));
+          }
+
+          // Move `idx` past the closing tag
+          idx = end + closing.length;
+          lastPos = idx; // Update the last position
+          continue;
+        }
+      }
+    }
+
+    idx++;
+  }
+
+  // Append any remaining content after the last pattern
+  if (lastPos < len) {
+    result.push(content.slice(lastPos));
+  }
+
+  return result.join('');
+}
diff --git a/lib/util/yaml.ts b/lib/util/yaml.ts
index ff78f31db54246f9049f93902d8ad1de33f30bd0..cd898fad46df26ff02baaba6f8e9d0bbc95f5bde 100644
--- a/lib/util/yaml.ts
+++ b/lib/util/yaml.ts
@@ -10,6 +10,7 @@ import { parseAllDocuments, parseDocument, stringify } from 'yaml';
 import type { ZodType } from 'zod';
 import { logger } from '../logger';
 import { regEx } from './regex';
+import { stripTemplates } from './string';
 
 export interface YamlOptions<
   ResT = unknown,
@@ -167,12 +168,7 @@ export function dump(obj: any, opts?: DumpOptions): string {
 
 function massageContent(content: string, options?: YamlOptions): string {
   if (options?.removeTemplates) {
-    return content
-      .replace(regEx(/\s+{{.+?}}:.+/gs), '')
-      .replace(regEx(/{{`.+?`}}/gs), '')
-      .replace(regEx(/{{.+?}}/gs), '')
-      .replace(regEx(/{%`.+?`%}/gs), '')
-      .replace(regEx(/{%.+?%}/g), '');
+    return stripTemplates(content.replace(regEx(/\s+{{.+?}}:.+/gs), ''));
   }
 
   return content;