我使用Python Regex遇到了一个小问题。
假设这是输入:
(zyx)bc
我想要实现的是获得括号中的任何内容作为单个匹配,以及任何外部的char作为单独的匹配。期望的结果将是:
['zyx','b','c']
应保留比赛顺序。
我尝试用Python 3.3获得这个,但似乎无法弄清楚正确的Regex。到目前为止,我有:
matches = findall(r'\((.*?)\)|\w', '(zyx)bc')
print(matches)
产生以下结果:
['zyx','','']
任何想法我做错了什么?
答案 0 :(得分:12)
来自re.findall
的文档:
如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。
当你的正则表达式匹配字符串三次时,(.*?)
组在后两次匹配时为空。如果你想要正则表达式的另一半的输出,你可以添加第二组:
>>> re.findall(r'\((.*?)\)|(\w)', '(zyx)bc')
[('zyx', ''), ('', 'b'), ('', 'c')]
或者,您可以删除所有组以再次获得简单的字符串列表:
>>> re.findall(r'\(.*?\)|\w', '(zyx)bc')
['(zyx)', 'b', 'c']
您需要手动删除括号。
答案 1 :(得分:2)
让我们看看使用re.DEBUG
的输出。
branch
literal 40
subpattern 1
min_repeat 0 65535
any None
literal 41
or
in
category category_word
哎呀,那里只有一个subpattern
,但re.findall
只有subpattern
才会出现!{/ p>
a = re.findall(r'\((.*?)\)|(.)', '(zyx)bc',re.DEBUG); a
[('zyx', ''), ('', 'b'), ('', 'c')]
branch
literal 40
subpattern 1
min_repeat 0 65535
any None
literal 41
or
subpattern 2
any None
更好。 :)
现在我们只需要将其设置为您想要的格式。
[i[0] if i[0] != '' else i[1] for i in a]
['zyx', 'b', 'c']
答案 2 :(得分:1)
文档特别提到了对待组,所以不要在括号模式周围放置一个组,并且你将获得所有内容,但是你需要自己从匹配的数据中删除parens:
>>> re.findall(r'\(.+?\)|\w', '(zyx)bc')
['(zyx)', 'b', 'c']
或使用更多组,然后处理生成的元组以获取您寻找的字符串:
>>> [''.join(t) for t in re.findall(r'\((.+?)\)|(\w)', '(zyx)bc')]
>>> ['zyx', 'b', 'c']
答案 3 :(得分:1)
In [108]: strs="(zyx)bc"
In [109]: re.findall(r"\(\w+\)|\w",strs)
Out[109]: ['(zyx)', 'b', 'c']
In [110]: [x.strip("()") for x in re.findall(r"\(\w+\)|\w",strs)]
Out[110]: ['zyx', 'b', 'c']
答案 4 :(得分:1)
其他答案向您展示了如何获得所需的结果,但需要手动删除括号的额外步骤。如果在正则表达式中使用外观,则无需手动剥离括号:
>>> import re
>>> s = '(zyx)bc'
>>> print (re.findall(r'(?<=\()\w+(?=\))|\w', s))
['zyx', 'b', 'c']
说明:
(?<=\() // lookbehind for left parenthesis
\w+ // all characters until:
(?=\)) // lookahead for right parenthesis
| // OR
\w // any character