一覧へ

正規表現で配列データをパースする

Python reモジュールでFASTAヘッダーのパース、配列パターン検索、データ抽出をする。バイオ研究者向け正規表現ガイド。

入門
|
60
|
検証済み (2026-06)
正規表現regexFASTAパターンマッチング配列パースreモジュール
進捗0/7 (0%)

正規表現で配列データをパースする

このトピックを終えたら

Pythonのreモジュールでテキストからパターンを検索し、FASTAヘッダーから情報を抽出し、配列データを検証できるようになります。


正規表現が必要な場面

FASTAファイルのヘッダーを見てみましょう:

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

この1行から「P04637」(UniProt ID)だけを抽出したいとします。split("|")で文字列を分割することもできますが、ヘッダー形式がファイルごとに異なると、毎回違うコードを書く必要があります。

**正規表現(Regular Expression、regex)**は「パターン」でテキストを検索します。「パイプ記号の間にある英数字」のようなパターンを定義すれば、どんな形式のヘッダーでも同じコードで抽出できます。

実験での例え — 特定の抗体が特定のエピトープ(パターン)に結合するように、正規表現はテキストの特定パターンに「結合」します。

Python reモジュールの基礎

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}")
assert value == 12.5

re.search(パターン, テキスト) — テキストからパターンに一致する最初の部分を見つけます。

主要パターン文字

パターン意味マッチ結果
\d数字1つ\d\d"42"
\d+数字1つ以上\d+"123", "4"
\w英数字+アンダースコア\w+"gene_1"
.任意の1文字a.b"a1b", "a-b"
*前のパターン0回以上ab*c"ac", "abc", "abbc"
+前のパターン1回以上ab+c"abc", "abbc"(acはX)
?前のパターン0または1回colou?r"color", "colour"
[ABC]A、B、Cのいずれか[ATGC]+"ATGCGTA"
^行の先頭^>FASTAヘッダー行
|または(OR)cat|dog"cat"または"dog"

パターンの前にrを付けるとraw stringになります(r"\d+")。バックスラッシュ(\)がPython文字列のエスケープと衝突するのを防ぎます。正規表現では常にr"..."形式を使ってください。

実践:FASTAヘッダーのパース

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)}")

出力:

text
UniProt ID: P04637
Organism: Homo sapiens

() — 括弧で囲んだ部分がキャプチャグループです。group(1)で括弧内の内容だけを抽出します。

.+??を付けると最小マッチ(lazy match)になります。できるだけ少なくマッチします。?なしの.+はできるだけ多くマッチする(greedy)ため、意図と異なる結果になることがあります。

実践:DNA配列からモチーフを探す

特定の制限酵素認識部位を配列からすべて見つけたい時:

python
import re
sequence = "ATCGAATTCGCGAATTCTTGAATTCAA"
# EcoRI認識部位: GAATTC
sites = [m.start() for m in re.finditer(r"GAATTC", sequence)]
print(f"EcoRI切断位置: {sites}")
print(f"切断部位数: {len(sites)}")
assert len(sites) == 3
assert sites == [4, 13, 20]

re.finditer()はすべてのマッチを繰り返し見つけます。re.search()は最初の1つだけですが、finditer()は全部見つけます。

実践:配列の検証

入力された配列が有効なDNA配列かどうかを検証します:

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() — 文字列全体がパターンと一致する必要があります。re.search()と違い、部分マッチは許可されません。

reモジュール主要関数一覧

関数用途戻り値
re.search(パターン, テキスト)最初のマッチを探すMatchオブジェクトまたは None
re.findall(パターン, テキスト)すべてのマッチをリストで文字列リスト
re.finditer(パターン, テキスト)すべてのマッチを巡回Matchオブジェクトiterator
re.sub(パターン, 置換, テキスト)パターンを別の文字列に置換新しい文字列
re.fullmatch(パターン, テキスト)全体がパターンに一致するかMatchオブジェクトまたは None

やってみよう(Faded Example)

空欄を埋めて、FASTAヘッダーから遺伝子名を抽出するコードを完成させてください。

穴埋め問題python
import
header = ">gene_BRCA1 | Homo sapiens | chromosome 17"
match = re.(r"gene_(\w+)", header)
if match:
gene_name = match.group()
print(f"遺伝子: {gene_name}")

よくあるエラーと解決法

Q: パターンは合っているのにNoneが返されます

大文字・小文字を確認してください。re.search(r"gaattc", "GAATTC")はマッチしません。大文字・小文字を無視するにはre.IGNORECASEフラグを追加してください:re.search(r"gaattc", "GAATTC", re.IGNORECASE)

Q: \dが動作しません

文字列の前にrを付けたか確認してください。"\d"はPythonが\dをエスケープシーケンスとして解釈しようとします。r"\d"にすればraw stringとして処理され、正規表現エンジンにそのまま渡されます。

Q: 正規表現が複雑すぎます。必ず使わなければなりませんか?

簡単な場合はinstartswith()split()などの文字列メソッドの方が読みやすいです。正規表現はパターンが複雑な場合や、複数の形式を一度に処理する必要がある時に力を発揮します。「Ctrl+Fではできない検索」が必要なら、正規表現を使いましょう。

💬 質問・コメント

0件のコメント

ログインせずに投稿できます。ゲスト投稿は投稿者自身で編集・削除できません。

0/2000

読み込み中...