Back to List

Parsing Sequence Data with Regular Expressions

Parse FASTA headers, search sequence patterns, and extract data with Python's re module. A regex guide for bio researchers.

Beginner
|
60min
|
Verified (2026-06)
Regular ExpressionregexFASTAPattern MatchingSequence Parsingre module
Progress0/7 (0%)

Parsing Sequence Data with Regular Expressions

After Completing This Topic

You'll be able to search for patterns in text with Python's re module, extract information from FASTA headers, and validate sequence data.


When You Need Regular Expressions

Let's look at a FASTA file header:

text
>sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606

You want to extract just "P04637" (the UniProt ID) from this line. You could split the string with split("|"), but if the header format varies across files, you'd need different code each time.

Regular expressions (regex) search text by "pattern." Define a pattern like "alphanumeric characters between pipe symbols," and you can use the same code to extract from any header format.

Lab analogy โ€” just as an antibody binds to a specific epitope (pattern), regular expressions "bind" to specific patterns in text.

Python re Module Basics

python
import re
text = "EGFR expression: 12.5 ng/mL"
match = re.search(r"\d+\.\d+", text)
if match:
value = float(match.group())
print(f"Value: {value}")
assert value == 12.5

re.search(pattern, text) โ€” finds the first part of the text that matches the pattern.

Core Pattern Characters

PatternMeaningExampleMatch
\dOne digit\d\d"42"
\d+One or more digits\d+"123", "4"
\wAlphanumeric + underscore\w+"gene_1"
.Any single charactera.b"a1b", "a-b"
*Previous pattern 0+ timesab*c"ac", "abc", "abbc"
+Previous pattern 1+ timesab+c"abc", "abbc" (not "ac")
?Previous pattern 0 or 1 timecolou?r"color", "colour"
[ABC]One of A, B, C[ATGC]+"ATGCGTA"
^Start of line^>FASTA header line
|Or (OR)cat|dog"cat" or "dog"

Prefixing patterns with r makes them raw strings (r"\d+"). This prevents backslashes (\) from conflicting with Python string escape sequences. Always use r"..." for regular expressions.

Practical: Parsing FASTA Headers

python
import re
header = ">sp|P04637|P53_HUMAN Cellular tumor antigen p53 OS=Homo sapiens OX=9606"
uniprot_id = re.search(r"\|(\w+)\|", header)
if uniprot_id:
print(f"UniProt ID: {uniprot_id.group(1)}")
organism = re.search(r"OS=(.+?) OX=", header)
if organism:
print(f"Organism: {organism.group(1)}")

Output:

text
UniProt ID: P04637
Organism: Homo sapiens

() โ€” the part inside parentheses is a capture group. Use group(1) to extract only the content within the parentheses.

.+? โ€” adding ? makes it a lazy match (minimum matching). It matches as little as possible. Without ?, .+ matches as much as possible (greedy), which may produce unexpected results.

Practical: Finding Motifs in DNA Sequences

When you want to find all restriction enzyme recognition sites in a sequence:

python
import re
sequence = "ATCGAATTCGCGAATTCTTGAATTCAA"
# EcoRI recognition site: GAATTC
sites = [m.start() for m in re.finditer(r"GAATTC", sequence)]
print(f"EcoRI cut positions: {sites}")
print(f"Number of cut sites: {len(sites)}")
assert len(sites) == 3
assert sites == [4, 13, 20]

re.finditer() finds all matches iteratively. re.search() finds only the first, but finditer() finds them all.

Practical: Sequence Validation

Validate whether an input sequence is a valid DNA sequence:

python
import re
def is_valid_dna(seq: str) -> bool:
return bool(re.fullmatch(r"[ATGCatgc]+", seq))
print(is_valid_dna("ATGCGATCGA"))
print(is_valid_dna("ATGXYZ"))
print(is_valid_dna(""))
assert is_valid_dna("ATGCGATCGA") == True
assert is_valid_dna("ATGXYZ") == False
assert is_valid_dna("") == False

re.fullmatch() โ€” the entire string must match the pattern. Unlike re.search(), partial matches are not allowed.

re Module Key Functions

FunctionPurposeReturns
re.search(pattern, text)Find first matchMatch object or None
re.findall(pattern, text)All matches as a listList of strings
re.finditer(pattern, text)Iterate all matchesMatch object iterator
re.sub(pattern, replacement, text)Replace patternNew string
re.fullmatch(pattern, text)Check full string matchMatch object or None

Try It Yourself (Faded Example)

Fill in the blanks to complete a code that extracts the gene name from a FASTA header.

Fill in the Blankspython
import
header = ">gene_BRCA1 | Homo sapiens | chromosome 17"
match = re.(r"gene_(\w+)", header)
if match:
gene_name = match.group()
print(f"Gene: {gene_name}")

Common Errors & Solutions

Q: The pattern seems right but None is returned

Check the case. re.search(r"gaattc", "GAATTC") won't match. To ignore case, add the re.IGNORECASE flag: re.search(r"gaattc", "GAATTC", re.IGNORECASE)

Q: \d doesn't work

Check if you prefixed the string with r. "\d" causes Python to try interpreting \d as an escape sequence. Using r"\d" treats it as a raw string, passing it directly to the regex engine.

Q: Regular expressions are too complex. Do I have to use them?

For simple cases, string methods like in, startswith(), split() are more readable. Regular expressions shine when patterns are complex or you need to handle multiple formats at once. If you need a "search that Ctrl+F can't do," that's when you use regex.

๐Ÿ’ฌ Questions & Comments

0 comments

You can post without signing in. Guest comments cannot be edited or deleted by their author.

0/2000

Loading...