Получить данные из строки

У меня есть строка, содержащая псевдоним игрока 1, ссылку на профиль игрока 1, псевдоним игрока 2, ссылку на профиль игрока 2, оружие. Мне нужно получить эти данные из строки ниже

[ex.endermen](profile_url1) got killed by [og.[(Z)]arcus(0.43k/d)](profile_url2) (FN Evolys, 56.83m)

Мне нужно получить данные и вывести их в формате

print(f"name1 = {name1}") print(f"name1_url = {name1_url}") print(f"name2 = {name2}") print(f"name2_url = {name2_url}")

есть ли способ правильно получить всю информацию, при условии, что строка может измениться на эту

[ex.endermen](profile_url1) got killed by [og.[(Z)]arcus(0.43k/d)](profile_url2) (FN Evolys, 56.83m)

или [ex.endermen](profile_url1) got killed by [platina](profile_url2) (FN Evolys, 56.83m) ?

Я пытался сделать это несколькими способами, используя регулярные выражения, но получил тот же результат, который меня не удовлетворил.

 name_weapon_pattern = r"\[(.*?)\].*\((.*?)\).*\((.*),.*\)"
 name_weapon_match = re.search(name_weapon_pattern, string)

 url_pattern = r"\((.*?)\)"
 url_match = re.findall(url_pattern, string)

 name1 = name_weapon_match.group(1)
 name1_url = name_weapon_match.group(2)
 name2 = name_weapon_match.group(3)
 name2_url = url_match[1]

 print(f"name1 = {name1}")
 print(f"name1_url = {name1_url}")
 print(f"name2 = {name2}")
 print(f"name2_url = {name2_url}")

результат:

name1 = og.[(Z)
name1_url = name2_url
name2 = FN Evolys
name2_url = 0.43k/d

Вместо того, чтобы заново изобретать колесо с регулярными выражениями, я бы предложил изучить существующие парсеры Python Markdown, которые на самом деле будут обрабатывать все крайние случаи, которые регулярные выражения либо не будут обрабатывать, либо потребуют для полной обработки нечитаемых шаблонов из сотен с лишним символов.

ShadowRanger 19.04.2023 00:34
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуй это

import re

def extract_players(string):
  name_weapon_pattern  = r"\[(.*?)\].*\((.*?)\).*\[(.*?)\].*\((.*?)\).*\((.*?),.*?\)"
  name_weapon_match = re.search(name_weapon_pattern, string)
  name1 = name_weapon_match.group(1)
  name1_url = name_weapon_match.group(2)
  name2 = name_weapon_match.group(3)
  name2_url = name_weapon_match.group(4)
  return (name1, name1_url, name2, name2_url)

# Test the function with different strings
string_1 = "[ex.endermen](profile_url1) got killed by [og.[(Z)]arcus(0.43k/d)](profile_url2) (FN Evolys, 56.83m)"
string_2= "[ex.endermen](profile_url1) got killed by [platina](profile_url2) (FN Evolys, 56.83m)"
string_3  = "[ex.endermen](profile_url1) got killed by [og.[(Z)]arcus(0.43k/d)](profile_url2) (FN Evolys, 56.83m)"  

print(extract_players(string_1))
print(extract_players(string_2))
print(extract_players(string_3))

Выход:

('ex.endermen', 'profile_url1', '(Z)', 'profile_url2')
('ex.endermen', 'profile_url1', 'platina', 'profile_url2')
('ex.endermen', 'profile_url1', '(Z)', 'profile_url2')

результат должен быть таким ('ex.endermen', 'profile_url1', 'og.[(Z)]arcus(0.43k/d)', 'profile_url2')

PLATINA 19.04.2023 01:07
Ответ принят как подходящий

Я согласен с @shadowranger в том, что регулярное выражение, вероятно, не является оптимальным инструментом для этого варианта использования. Но в любом случае есть мое решение с использованием named_groups:

import re

p = re.compile(r"\[(?P<name1>.*?)\]\((?P<name1_url>.*?)\).*?\[(?P<name2>.*?)\]\((?P<name2_url>.*?)\)\s\((?P<weapons>.*)\)$")

text = '[ex.endermen](profile_url1) got killed by [og.[(Z)]arcus(0.43k/d)](profile_url2) (FN Evolys, 56.83m)'

p.match(text).groupdict()

# outputs
# {'name1': 'ex.endermen',
#  'name1_url': 'profile_url1',
#  'name2': 'og.[(Z)]arcus(0.43k/d)',
#  'name2_url': 'profile_url2',
#  'weapons': 'FN Evolys, 56.83m'}

text = '[ex.endermen](profile_url1) got killed by [platina](profile_url2) (FN Evolys, 56.83m)'

p.match(text).groupdict()

# outputs
# {'name1': 'ex.endermen',
#  'name1_url': 'profile_url1',
#  'name2': 'platina',
#  'name2_url': 'profile_url2',
#  'weapons': 'FN Evolys, 56.83m'}

# you can access individual groups with
m = p.match(text)
m["name1"]
# > 'ex.endermen'

Проблема с вложенными скобками может быть решена с помощью рекурсивного шаблона (который не поддерживается в re, вам нужно будет использовать regex), но в этом случае мы можем найти name2 путем сопоставления ]( символов. Это явно ломается, когда имя2 содержит эту последовательность.

Другие вопросы по теме