Участник:Гиперболоид инженера Мошонкина/скрипт: различия между версиями
Перейти к навигации
Перейти к поиску
Daruk (обсуждение | вклад) Нет описания правки |
LordBot (обсуждение | вклад) м Замена текста — «lang="py">» на «lang="python" line>» |
||
| (не показано 5 промежуточных версий 2 участников) | |||
| Строка 1: | Строка 1: | ||
<syntaxhighlight lang=" | <syntaxhighlight lang="python" line> | ||
import re | |||
import string | |||
def convert_to_lua(wiki_text): | def convert_to_lua(wiki_text, group_prefix=""): | ||
lua_output = ["return {", ' ["Tournament_Data"] = {'] | lua_output = ["return {", ' ["Tournament_Data"] = {'] | ||
# --- 1. Парсинг групп --- | # --- 1. Парсинг групп --- | ||
group_pattern = re.compile( | group_pattern = re.compile( | ||
r'(?:;\s*Группа\s+([^\n]+)\s*)?\{\{Группа\s+(\d+)-А(\d+)\s*\|?(.*?)\}\}', | r'(?:;\s*Группа\s+([^\n]+)\s*)?\{\{Группа\s+(\d+)-А(\d+)\s*\|?(.*?)\}\}', | ||
| Строка 11: | Строка 12: | ||
) | ) | ||
group_index = 0 | |||
for match in group_pattern.finditer(wiki_text): | for match in group_pattern.finditer(wiki_text): | ||
# Генерируем литеру группы: 0 -> A, 1 -> B, 2 -> C и т.д. | |||
group_letter = chr(65 + group_index) | |||
group_index += 1 | |||
# Формируем имя таблицы группы в зависимости от наличия префикса | |||
if group_prefix: | |||
lua_group_name = f"{group_prefix}_Group{group_letter}" | |||
else: | |||
old_name = match.group(1).strip() if match.group(1) else f"Unnamed_{group_index}" | |||
lua_group_name = f"Group_{old_name}" | |||
num_teams = int(match.group(2)) | num_teams = int(match.group(2)) | ||
legs_indicator = int(match.group(3)) | legs_indicator = int(match.group(3)) | ||
leg_val = 1 if legs_indicator == 2 else 0 | leg_val = 1 if legs_indicator == 2 else 0 | ||
body = match.group(4) | body = match.group(4) | ||
parts = [p.strip() for p in body.split('|')] | |||
parts = [p.strip() for p in body.split('|' | |||
teams = [] | teams = [] | ||
chunk_size = num_teams + 1 | chunk_size = num_teams + 1 | ||
for i in range(num_teams): | for i in range(num_teams): | ||
chunk = parts[i * chunk_size : (i + 1) * chunk_size] | chunk = parts[i * chunk_size : (i + 1) * chunk_size] | ||
if | if len(chunk) < chunk_size: continue | ||
status = chunk[0].replace('LY', 'L') | status = chunk[0].replace('LY', 'L') | ||
name = chunk[1] | name = chunk[1] | ||
| Строка 36: | Строка 43: | ||
teams.append({"name": name, "status": status, "scores": scores}) | teams.append({"name": name, "status": status, "scores": scores}) | ||
lua_output.append(f'\n ["{lua_group_name}"] = {{') | |||
lua_output.append(f'\n [" | |||
lua_output.append(' type = "group",') | lua_output.append(' type = "group",') | ||
lua_output.append(f' number_of_rounds = {legs_indicator},') # <-- ДОБАВЛЕНО ДЛЯ ГРУПП | |||
lua_output.append(' standings = {') | lua_output.append(' standings = {') | ||
for t in teams: | for t in teams: | ||
| Строка 45: | Строка 52: | ||
lua_output.append(' matches = {') | lua_output.append(' matches = {') | ||
# | # Распределение матчей | ||
for i, team in enumerate(teams): | for i, team in enumerate(teams): | ||
score_idx = 0 | score_idx = 0 | ||
for j, opp in enumerate(teams): | for j, opp in enumerate(teams): | ||
if i == j: continue | if i == j: continue | ||
if score_idx < len(team["scores"]): | if score_idx < len(team["scores"]): | ||
score_str = team["scores"][score_idx] | score_str = team["scores"][score_idx] | ||
score_idx += 1 | score_idx += 1 | ||
if ':' in score_str: | |||
if leg_val == 1 or (leg_val == 0 and i < j): | |||
if ':' in score_str: | |||
g1, g2 = score_str.split(':') | |||
lua_output.append(f' {{"{team["name"]}", "{opp["name"]}", {g1.strip()}, {g2.strip()}, {leg_val}}},') | |||
lua_output.append(' }') | lua_output.append(' }') | ||
| Строка 61: | Строка 71: | ||
# --- 2. Парсинг матчей на вылет --- | # --- 2. Парсинг матчей на вылет --- | ||
knockout_pattern = re.compile(r'\{\{И\d+\s*\|?(.*?)\}\}', re.IGNORECASE | re.DOTALL) | knockout_pattern = re.compile(r'\{\{И\d+\s*\|?(.*?)\}\}', re.IGNORECASE | re.DOTALL) | ||
ko_counter = 1 | ko_counter = 1 | ||
| Строка 67: | Строка 76: | ||
for match in knockout_pattern.finditer(wiki_text): | for match in knockout_pattern.finditer(wiki_text): | ||
body = match.group(1) | body = match.group(1) | ||
parts = [p.strip() for p in body.split('|') if | parts = [p.strip() for p in body.split('|')] | ||
# --- ДОБАВЛЕНО: Определяем количество кругов для плей-офф --- | |||
ko_rounds = 1 | |||
for i in range(0, len(parts), 5): | |||
chunk = parts[i:i+5] | |||
if len(chunk) >= 3: | |||
base_scores = chunk[2].split('(')[0] # отсекаем пенальти/доп.время для проверки | |||
if ',' in base_scores: | |||
ko_rounds = 2 | |||
break | |||
# ------------------------------------------------------------- | |||
lua_output.append(f'\n ["Knockout_Stage_{ko_counter}"] = {{') | lua_output.append(f'\n ["Knockout_Stage_{ko_counter}"] = {{') | ||
lua_output.append(' type = "knockout",') | lua_output.append(' type = "knockout",') | ||
lua_output.append(f' number_of_rounds = {ko_rounds},') # <-- ДОБАВЛЕНО ДЛЯ ПЛЕЙ-ОФФ | |||
lua_output.append(' matches = {') | lua_output.append(' matches = {') | ||
ko_counter += 1 | ko_counter += 1 | ||
for i in range(0, len(parts), 5): | for i in range(0, len(parts), 5): | ||
chunk = parts[i:i+5] | chunk = parts[i:i+5] | ||
| Строка 85: | Строка 105: | ||
st2 = chunk[4].replace('LY', 'L') | st2 = chunk[4].replace('LY', 'L') | ||
mod = "nil" | mod = "nil" | ||
p1, p2 = "nil", "nil" | p1, p2 = "nil", "nil" | ||
base_scores = score_str | base_scores = score_str | ||
if '(' in score_str: | if '(' in score_str: | ||
base_scores, ext = score_str.split('(', 1) | base_scores, ext = score_str.split('(', 1) | ||
base_scores = base_scores.strip() | |||
ext = ext.replace(')', '').strip().lower() | ext = ext.replace(')', '').strip().lower() | ||
if 'et' in ext: | if 'et' in ext or 'дв' in ext: | ||
mod = '"aet"' | mod = '"aet"' | ||
elif 'пен' in ext: | elif 'пен' in ext or 'pen' in ext: | ||
mod = '"pen"' | mod = '"pen"' | ||
pen_match = re.search(r'(\d+):(\d+)', ext) | pen_match = re.search(r'(\d+):(\d+)', ext) | ||
| Строка 104: | Строка 122: | ||
p1, p2 = pen_match.groups() | p1, p2 = pen_match.groups() | ||
matches_list = [s.strip() for s in base_scores.split(',')] | |||
if len(matches_list) == 2: | |||
lua_output.append( | m1 = matches_list[0] | ||
m2 = matches_list[1] | |||
g1_1, g2_1 = "nil", "nil" | |||
if ':' in m1: | |||
g1_1, g2_1 = [x.strip() for x in m1.split(':')] | |||
g1_2, g2_2 = "nil", "nil" | |||
if ':' in m2: | |||
g1_2, g2_2 = [x.strip() for x in m2.split(':')] | |||
lua_output.append( | |||
f' {{"{t1}", "{t2}", {g1_1}, {g2_1}, {g1_2}, {g2_2}, {mod}, {p1}, {p2}, "{st1}", "{st2}"}},' | |||
) | |||
else: | |||
m1 = matches_list[0] | |||
g1, g2 = "nil", "nil" | |||
if ':' in m1: | |||
g1, g2 = [x.strip() for x in m1.split(':')] | |||
lua_output.append( | |||
f' {{"{t1}", "{t2}", {g1}, {g2}, {mod}, {p1}, {p2}, "{st1}", "{st2}", 1}},' | |||
) | |||
lua_output.append(' }') | lua_output.append(' }') | ||
| Строка 127: | Строка 159: | ||
# --- ЗАПУСК --- | # --- ЗАПУСК --- | ||
if __name__ == "__main__": | if __name__ == "__main__": | ||
# Сюда | # Сюда вписываем нужный префикс. Если оставить "", будет работать как раньше. | ||
PREFIX = "1R" | |||
data = """ | data = """ | ||
""" | """ | ||
result = convert_to_lua(data | # Передаем префикс вторым аргументом | ||
result = convert_to_lua(data, group_prefix=PREFIX) | |||
print(result) | print(result) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Текущая версия от 14:48, 30 мая 2026
import re
import string
def convert_to_lua(wiki_text, group_prefix=""):
lua_output = ["return {", ' ["Tournament_Data"] = {']
# --- 1. Парсинг групп ---
group_pattern = re.compile(
r'(?:;\s*Группа\s+([^\n]+)\s*)?\{\{Группа\s+(\d+)-А(\d+)\s*\|?(.*?)\}\}',
re.IGNORECASE | re.DOTALL
)
group_index = 0
for match in group_pattern.finditer(wiki_text):
# Генерируем литеру группы: 0 -> A, 1 -> B, 2 -> C и т.д.
group_letter = chr(65 + group_index)
group_index += 1
# Формируем имя таблицы группы в зависимости от наличия префикса
if group_prefix:
lua_group_name = f"{group_prefix}_Group{group_letter}"
else:
old_name = match.group(1).strip() if match.group(1) else f"Unnamed_{group_index}"
lua_group_name = f"Group_{old_name}"
num_teams = int(match.group(2))
legs_indicator = int(match.group(3))
leg_val = 1 if legs_indicator == 2 else 0
body = match.group(4)
parts = [p.strip() for p in body.split('|')]
teams = []
chunk_size = num_teams + 1
for i in range(num_teams):
chunk = parts[i * chunk_size : (i + 1) * chunk_size]
if len(chunk) < chunk_size: continue
status = chunk[0].replace('LY', 'L')
name = chunk[1]
scores = chunk[2:]
teams.append({"name": name, "status": status, "scores": scores})
lua_output.append(f'\n ["{lua_group_name}"] = {{')
lua_output.append(' type = "group",')
lua_output.append(f' number_of_rounds = {legs_indicator},') # <-- ДОБАВЛЕНО ДЛЯ ГРУПП
lua_output.append(' standings = {')
for t in teams:
lua_output.append(f' {{"{t["name"]}", "{t["status"]}"}},')
lua_output.append(' },')
lua_output.append(' matches = {')
# Распределение матчей
for i, team in enumerate(teams):
score_idx = 0
for j, opp in enumerate(teams):
if i == j: continue
if score_idx < len(team["scores"]):
score_str = team["scores"][score_idx]
score_idx += 1
if leg_val == 1 or (leg_val == 0 and i < j):
if ':' in score_str:
g1, g2 = score_str.split(':')
lua_output.append(f' {{"{team["name"]}", "{opp["name"]}", {g1.strip()}, {g2.strip()}, {leg_val}}},')
lua_output.append(' }')
lua_output.append(' },')
# --- 2. Парсинг матчей на вылет ---
knockout_pattern = re.compile(r'\{\{И\d+\s*\|?(.*?)\}\}', re.IGNORECASE | re.DOTALL)
ko_counter = 1
for match in knockout_pattern.finditer(wiki_text):
body = match.group(1)
parts = [p.strip() for p in body.split('|')]
# --- ДОБАВЛЕНО: Определяем количество кругов для плей-офф ---
ko_rounds = 1
for i in range(0, len(parts), 5):
chunk = parts[i:i+5]
if len(chunk) >= 3:
base_scores = chunk[2].split('(')[0] # отсекаем пенальти/доп.время для проверки
if ',' in base_scores:
ko_rounds = 2
break
# -------------------------------------------------------------
lua_output.append(f'\n ["Knockout_Stage_{ko_counter}"] = {{')
lua_output.append(' type = "knockout",')
lua_output.append(f' number_of_rounds = {ko_rounds},') # <-- ДОБАВЛЕНО ДЛЯ ПЛЕЙ-ОФФ
lua_output.append(' matches = {')
ko_counter += 1
for i in range(0, len(parts), 5):
chunk = parts[i:i+5]
if len(chunk) < 5: continue
st1 = chunk[0].replace('LY', 'L')
t1 = chunk[1]
score_str = chunk[2]
t2 = chunk[3]
st2 = chunk[4].replace('LY', 'L')
mod = "nil"
p1, p2 = "nil", "nil"
base_scores = score_str
if '(' in score_str:
base_scores, ext = score_str.split('(', 1)
base_scores = base_scores.strip()
ext = ext.replace(')', '').strip().lower()
if 'et' in ext or 'дв' in ext:
mod = '"aet"'
elif 'пен' in ext or 'pen' in ext:
mod = '"pen"'
pen_match = re.search(r'(\d+):(\d+)', ext)
if pen_match:
p1, p2 = pen_match.groups()
matches_list = [s.strip() for s in base_scores.split(',')]
if len(matches_list) == 2:
m1 = matches_list[0]
m2 = matches_list[1]
g1_1, g2_1 = "nil", "nil"
if ':' in m1:
g1_1, g2_1 = [x.strip() for x in m1.split(':')]
g1_2, g2_2 = "nil", "nil"
if ':' in m2:
g1_2, g2_2 = [x.strip() for x in m2.split(':')]
lua_output.append(
f' {{"{t1}", "{t2}", {g1_1}, {g2_1}, {g1_2}, {g2_2}, {mod}, {p1}, {p2}, "{st1}", "{st2}"}},'
)
else:
m1 = matches_list[0]
g1, g2 = "nil", "nil"
if ':' in m1:
g1, g2 = [x.strip() for x in m1.split(':')]
lua_output.append(
f' {{"{t1}", "{t2}", {g1}, {g2}, {mod}, {p1}, {p2}, "{st1}", "{st2}", 1}},'
)
lua_output.append(' }')
lua_output.append(' },')
lua_output.append(" }")
lua_output.append("}")
return "\n".join(lua_output)
# --- ЗАПУСК ---
if __name__ == "__main__":
# Сюда вписываем нужный префикс. Если оставить "", будет работать как раньше.
PREFIX = "1R"
data = """
"""
# Передаем префикс вторым аргументом
result = convert_to_lua(data, group_prefix=PREFIX)
print(result)