How to Bulk-Delete Sentences from SRT Files Using Python
Have you ever downloaded subtitle files (.srt) for an entire season of a TV show, only to find that every single episode contains an annoying advertisement like "Subtitles synced by Subz.com"?
The Analogy: Manually opening and editing 100 episodes of an anime or TV show is like picking weeds in a massive field by hand. Python is the industrial lawnmower.
Most beginners try to solve this by writing a simple Python script using `str.replace()`. However, doing so will instantly corrupt your video playback experience. To process data like an expert, we need to understand the rigid structure of SRT files and use Regular Expressions (Regex).
An SRT file isn't just plain text; it's broken into rigid blocks containing an Index, a Timestamp, and the Text. If you use a basic text replace to delete the spam sentence, you leave behind the Index and Timestamp with a blank text field. Video players (like VLC or Plex) will literally display a blank, black box on your screen for 5 seconds. We must delete the entire block.
The Expert Python Script
Here is the robust, production-ready script. It uses Python's re (Regular Expressions) module to find and safely excise the entire ghost block, and it includes advanced file encoding fallbacks. Save this as srt_cleaner.py.
import os
import re
def delete_sentences_in_srt_files():
"""
Scans a directory for .srt files, uses Regex to safely delete the ENTIRE
subtitle block containing the target text, and saves it in a safe sandbox.
"""
source_directory = input("Enter the path to the folder containing the .srt files: ")
if not os.path.isdir(source_directory):
print(f"Error: Directory '{source_directory}' not found.")
return
sentences_input = input("Enter the sentences to delete (separate with a semicolon ';'): ")
sentences_to_delete = [s.strip() for s in sentences_input.split(';') if s.strip()]
if not sentences_to_delete:
print("No sentences provided. Exiting.")
return
# Advanced fallback encodings for downloaded files
encodings = ['utf-8', 'utf-8-sig', 'latin-1', 'cp1252']
updated_files_count = 0
print("\nStarting file processing...")
for root, _, files in os.walk(source_directory):
for filename in files:
if filename.lower().endswith(".srt"):
filepath = os.path.join(root, filename)
content = None
# 1. Safely read the file using encoding fallbacks
for enc in encodings:
try:
with open(filepath, 'r', encoding=enc) as f:
content = f.read()
break
except UnicodeDecodeError:
continue
if content is None:
print(f" -> Error: Could not decode {filename}. Skipping.")
continue
original_content = content
# 2. Use Regex as a laser scalpel to remove the entire block
for sentence in sentences_to_delete:
escaped_sentence = re.escape(sentence)
# Regex pattern to match Index, Timestamp, and Text up to the double newline
pattern = r'(?m)^\d+\n\d{2}:\d{2}:\d{2},\d{3} --> \d{2}:\d{2}:\d{2},\d{3}\n.*?' + escaped_sentence + r'.*?(?:\n\n|\Z)'
content = re.sub(pattern, '', content, flags=re.DOTALL)
# 3. Save to a safe sandbox if changes were made
if content != original_content:
# Clean up any leftover awkward newlines
content = re.sub(r'\n{3,}', '\n\n', content).strip()
relative_path = os.path.relpath(root, source_directory)
updated_subfolder_path = os.path.join(source_directory, "updated", relative_path)
os.makedirs(updated_subfolder_path, exist_ok=True)
output_filepath = os.path.join(updated_subfolder_path, filename)
with open(output_filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f" -> Cleaned: {filename}")
updated_files_count += 1
print(f"\nComplete! {updated_files_count} files were successfully cleaned.")
if __name__ == "__main__":
delete_sentences_in_srt_files()
Step-by-Step Code Breakdown
1. The Encoding Nightmare
If you download subtitles from the internet, you will quickly learn they are a mess. Some are saved in standard UTF-8, but older files might use Windows CP1252 or Latin-1.
Expert Tip: A naive script assumes utf-8 and will completely crash on episode 12 when it hits a weird character encoding. Our script iterates through an array of encodings = ['utf-8', 'utf-8-sig', 'latin-1', 'cp1252']. If it throws a UnicodeDecodeError, it gracefully catches it and tries the next encoding format on the list.
2. The Regex Laser Scalpel
If str.replace() is a blunt machete, Regular Expressions (Regex) are a laser scalpel. Here is exactly what our complex pattern is doing:
^\d+\n: Finds the block index number (e.g., "45") followed by a new line.\d{2}:\d{2}:\d{2},\d{3} --> ...: Finds the exact timestamp format (e.g., 00:01:23,400)..*?: Scans through the text until it hits your target sentence (theescaped_sentence).(?:\n\n|\Z): Selects everything up until it hits a double line break (the end of the block) or the end of the file.
Using re.sub(), we target this entire mass of text and replace it with nothing (''), cleanly excising the ghost block from existence.
3. The "Sandbox" Principle for Safe Data
A core rule of data manipulation is never mutate the source data. What if you made a typo in the sentence you wanted to delete? Overwriting the original files would destroy your entire subtitle library.
Instead, we use os.makedirs and os.path.relpath to perfectly clone your original folder structure into a safe updated/ sandbox directory. Your originals remain untouched, and the cleaned files are neatly organized exactly where they belong.