у меня это в файле
import re
sample = """Name: @s
Owner: @a[tag=Admin]"""
target = r"@[sae](\[[\w{}=, ]*\])?"
regex = re.split(target, sample)
print(regex)
Я хочу разделить все слова, начинающиеся с @
, вот так:["Name: ", "@s", "\nOwner: ", "@a[tag=Admin]"]
Но вместо этого выдает это:['Name: ', None, '\nOwner: ', '[tag=Admin]', '']
Как его отделить?
Я бы использовал re.findall
здесь:
sample = """Name: @s
Owner: @a[tag=Admin]"""
parts = re.findall(r'@\w+(?:\[.*?\])?|\s*\S+\s*', sample)
print(parts) # ['Name: ', '@s', '\nOwner: ', '@a[tag=Admin]']
Используемый здесь шаблон регулярного выражения говорит, что он соответствует:
@\w+ a tag @some_tag
(?:\[.*?\])? followed by an optional [...] term
| OR
\s*\S+\s* any other non whitespace term,
including optional whitespace on both sides
Если я правильно понимаю требования, вы можете сделать это следующим образом:
import re
s = """Name: @s
Owner: @a[tag=Admin]
"""
rgx = r'(?=@.*)|(?=\r?\n[^@\r\n]*)'
re.split(rgx, s)
#=> ['Name: ', '@s', '\nOwner: ', '@a[tag=Admin]\n']
Регулярное выражение можно разбить следующим образом.
(?= # begin a positive lookahead
@.* # match '@' followed by >= 0 chars other than line terminators
) # end positive lookahead
| # or
(?= # begin a positive lookahead
\r?\n # match a line terminator
[^@\r\n]* # match >= 0 characters other than '@' and line terminators
) # end positive lookahead
Обратите внимание, что совпадения имеют нулевую ширину.
@ Тим, я точно так же помог тебе с этим кольцом для гольфа 0,5 м.
re.split
ожидает, что регулярное выражение будет соответствовать разделителям в строке. Он возвращает только те части разделителей, которые равны захвачен. В случае вашего регулярного выражения это только часть между скобками, если они есть.
Если вы хотите, чтобы в списке отображался весь разделитель, заключите все регулярное выражение в круглые скобки:
target = r"(@[sae](\[[\w{}=, ]*\])?)"
Но вам, вероятно, лучше не захватывать внутреннюю группу. Вы можете изменить его на группу без захвата, используя (?:…)
вместо (…)
:
target = r"(@[sae](?:\[[\w{}=, ]*\])?)"
В вашем выводе вы сохраняете [tag=Admin]
, поскольку эта часть находится в группе захвата, а использование разделения также может возвращать пустые строки.
Другой вариант — указать разрешенный формат данных и вместо разделения захватывать части на 2 группы.
(\s*\w+:\s*)(@[sae](?:\[[\w{}=, ]*])?)
Шаблон соответствует:
(
Снять группа 1\s*\w+:\s*
Сопоставьте 1+ словесных символов и :
между необязательными пробелами)
Закрыть группу(
Захватить группа 2@[sae]
Совпадение @
, за которым следует либо s
a
e
(?:\[[\w{}=, ]*])?
По желанию совпадать [...]
)
Закрыть группуПример кода:
import re
sample = """Name: @s
Owner: @a[tag=Admin]"""
target = r"(\s*\w+:\s*)(@[sae](?:\[[\w{}=, ]*])?)"
listOfTuples = re.findall(target, sample)
lst = [s for tpl in listOfTuples for s in tpl]
print(lst)
Выход
['Name: ', '@s', '\nOwner: ', '@a[tag=Admin]']
См. демонстрация регулярных выражений и демонстрация Python.
Помогу получить футболку +1.