Как разделить пары ключ / значение SGF, такие как «A [B] [q] G [boy]»? - PullRequest
0 голосов
/ 06 января 2019

В Python я пытаюсь разбить строку с парами ключ / значение SGF на список или сопоставить объект следующим образом:

'A[B][q]G[boy]' --> ['A[B][q]', 'G[boy]']

(ключи «A» и «G», значения «[B] [q]» и «[boy]» соответственно.)

Я пытался разделить их с помощью этого шаблона регулярных выражений

pattern = r'([A-Z]\[.+\])[A-Z]'

Но это не получается, когда есть только один ключ / значение, например 'A [B]'

Есть предложения? Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 06 января 2019

Вы можете использовать это регулярное выражение для решения на основе разделения,

(?<=])(?=[A-Z])

Демонстрация для сплит-систем

Пример кода Python для решения на основе разделения,

import re

arr = ['A[B][q]G[boy]','A[B][q]']

for s in arr:
 splittedstr = re.split('(?<=])(?=[A-Z])', s)
 print(splittedstr)

печать

['A[B][q]', 'G[boy]']
['A[B][q]']

Если вам нужно решение на основе соответствия, вы можете использовать это регулярное выражение,

[A-Z](?:\[\w+])*

Демонстрация для матчей

Примеры кодов Python для решения на основе совпадений,

import re

arr = ['A[B][q]G[boy]','A[B][q]']

for s in arr:
 print(re.findall(r'[A-Z](?:\[\w+])*',s))

печать

['A[B][q]', 'G[boy]']
['A[B][q]']

Используйте любую, которая подходит вам больше всего.

0 голосов
/ 06 января 2019

Ваше регулярное выражение не соответствует всем форматам, потому что \[.+\] и [A-Z] требуют соответствия. .+ также является жадным совпадением и будет соответствовать до последнего появления ]

Вы можете использовать re.findall , сделать необязательным значение в первых квадратных скобках и повторить последнюю часть 0+ раз:

[A-Z](?:\[[A-Z]\])?(?:\[[a-z]+\])*

Объяснение

  • [A-Z] Соответствует заглавным буквам
  • (?:\[[A-Z]\])? Необязательная группа без захвата, которая соответствует [ заглавные буквы ]
  • (?:\[[a-z]+\])* Повторите 0+ раз [ 1+ строчные буквы ]

Regex demo | Python demo

Пример

import re
strings = ["A[B][q]G[boy]", "A[B][q]", "A[B]"]
for s in strings:
    print(re.findall(r"[A-Z](?:\[[A-Z]\])?(?:\[[a-z]+\])*", s))

Результат

['A[B][q]', 'G[boy]']
['A[B][q]']
['A[B]']

Примечание

Если вы хотите сопоставить несколько символов в верхнем регистре, вы можете использовать квантификатор [A-Z]+, и вы можете настроить то, что вы хотите сопоставить в классе символов *1047* соответственно.

0 голосов
/ 06 января 2019

С re.finditer функция:

import re

def find_sgf_groups(s: str):
    sgf_groups = []
    for m in re.finditer(r'[A-Z](\[[a-zA-Z]+\])+', s):
        sgf_groups.append(m.group())

    return sgf_groups

print(find_sgf_groups('A[B][q]'))
print(find_sgf_groups('A[B][q]G[boy]'))

Выход (последовательно):

['A[B][q]']
['A[B][q]', 'G[boy]']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...