Python 如何拆分SGF键/值对,如';A[B][q]G[男孩]和#x27;?

Python 如何拆分SGF键/值对,如';A[B][q]G[男孩]和#x27;?,python,regex,Python,Regex,在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]”,则此操作将失败 有什么建议吗?提前感谢。功能: import re def find_sgf_groups

在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]”,则此操作将失败

有什么建议吗?提前感谢。

功能:

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]'))
输出(按顺序):

具有以下功能:

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-Z])
import re

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

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

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

for s in arr:
 print(re.findall(r'[A-Z](?:\[\w+])*',s))
如果需要基于匹配的解决方案,可以使用此正则表达式

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

基于匹配的解决方案的python示例代码

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

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

for s in arr:
 splittedstr = re.split('(?<=])(?=[A-Z])', s)
 print(splittedstr)
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]']
['A[B][q]', 'G[boy]']
['A[B][q]']

使用最适合您的任何选项。

您可以将此正则表达式用于基于拆分的解决方案

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

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

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

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

for s in arr:
 print(re.findall(r'[A-Z](?:\[\w+])*',s))
如果需要基于匹配的解决方案,可以使用此正则表达式

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

基于匹配的解决方案的python示例代码

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

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

for s in arr:
 splittedstr = re.split('(?<=])(?=[A-Z])', s)
 print(splittedstr)
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]']
['A[B][q]', 'G[boy]']
['A[B][q]']

使用最适合您的任何格式。

您的正则表达式不匹配所有格式,因为
\[.+\]
[A-Z]
需要匹配
+
也是贪婪匹配,将一直匹配到最后一次出现
]

您可以使用并使第一个方括号之间的值为可选值,并将最后一部分重复0多次:

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

  • [A-Z]
    匹配大写字符
  • (?:\[[A-Z]\])?
    可选非捕获组,匹配
    [
    大写字符
    ]
  • (?:\[[a-z]+\])*
    重复0多次
    [
    1+小写字符
    ]
|

范例

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]+
,并相应地调整要匹配的内容。

您的正则表达式不匹配所有格式,因为
\[.+\]
[a-Z]
需要匹配
+
也是贪婪匹配,将一直匹配到最后一次出现
]

您可以使用并使第一个方括号之间的值为可选值,并将最后一部分重复0多次:

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

  • [A-Z]
    匹配大写字符
  • (?:\[[A-Z]\])?
    可选非捕获组,匹配
    [
    大写字符
    ]
  • (?:\[[a-z]+\])*
    重复0多次
    [
    1+小写字符
    ]
|

范例

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]+
,并相应地调整要匹配的内容。

您的意思是这样的吗?谢谢你的评论。您的正则表达式模式似乎适用于多个键/值输入,如“A[B][q]G[boy]”,但不适用于单个键/值输入,如“A[B][q]”。有什么想法吗?在这种情况下,你可以用问号将最后一部分变成可选的
([A-Z]\[[A-Z]\]\[[A-Z]\])([A-Z]\[[A-Z]+\])?
。你的意思是这样吗?谢谢你的评论。您的正则表达式模式似乎适用于多个键/值输入,如“A[B][q]G[boy]”,但不适用于单个键/值输入,如“A[B][q]”。有什么想法吗?在这种情况下,你可以用问号将最后一部分变成可选的
([A-Z]\[[A-Z]\]\[[A-Z]\])([A-Z]\[[A-Z]+\])?
。这就是我需要的。不知道芬迪特的存在。谢谢这就是我需要的。不知道芬迪特的存在。谢谢