62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
import re
|
|
|
|
def parse_deck_list(text):
|
|
"""
|
|
Parses a deck list string and returns a list of dictionaries with quantity, card name, and is_sideboard.
|
|
|
|
Supported formats:
|
|
- Arena/Moxfield: "1 Laughing Jasper Flint (OTJ) 215 *F*"
|
|
- MTGO: "1 Arcane Signet"
|
|
- Plain Text: "1 Arcane Signet"
|
|
|
|
Returns:
|
|
list of dict: [{'quantity': int, 'name': str, 'is_sideboard': bool}]
|
|
"""
|
|
lines = text.strip().split('\n')
|
|
parsed_cards = []
|
|
is_sideboard = False
|
|
|
|
# Regex for Arena/Moxfield lines: e.g., "1 Card Name (SET) 123"
|
|
# Captures: Qty, Name
|
|
# We ignore Set code and collector number for lookup simplicity for now, relying on name.
|
|
# Pattern: Digit+ space Name space (SetCode) space ...
|
|
arena_pattern = re.compile(r'^(\d+)\s+(.+?)\s+\([A-Z0-9]+\)\s+\S+')
|
|
|
|
# Regex for simple Quantity + Name: "1 Card Name"
|
|
simple_pattern = re.compile(r'^(\d+)\s+(.+)$')
|
|
|
|
for line in lines:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
|
|
if line.lower().startswith('sideboard'):
|
|
is_sideboard = True
|
|
continue
|
|
|
|
# Try Arena/Moxfield/detailed format first
|
|
match = arena_pattern.match(line)
|
|
if match:
|
|
qty = int(match.group(1))
|
|
name = match.group(2).strip()
|
|
parsed_cards.append({
|
|
'quantity': qty,
|
|
'name': name,
|
|
'is_sideboard': is_sideboard
|
|
})
|
|
continue
|
|
|
|
# Try simple format
|
|
match = simple_pattern.match(line)
|
|
if match:
|
|
qty = int(match.group(1))
|
|
name = match.group(2).strip()
|
|
parsed_cards.append({
|
|
'quantity': qty,
|
|
'name': name,
|
|
'is_sideboard': is_sideboard
|
|
})
|
|
continue
|
|
|
|
return parsed_cards
|