来自@ avinash-raj的回答:
re.findall(r'\([^\[\]()]*\[\([^\[\]()]+source=([\w./]+)', s)
修改后的问题:
我有以下字符串:
s=string='s=<a=1 b=[(text1 [(text2 source=x.gz i=i.gz)]), ([(text3 j=1.0 source=y.gz)])] c=[([(3)])] d=[([(source=x.gz)])]>'
我希望将此列表作为输出:
['x.gz','y.gz']
原始问题:
我有以下字符串:
s=string='s=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])]>'
我希望将此列表作为输出:
['x.gz','y.gz']
我试过这个:
re.findall(r'b=\[([^]]*)\]',s)
返回:
['([(source=x.gz i=0)']
我也试过这个:
re.findall(r'\[([^]]*)\]',s)
返回:
['([(source=x.gz i=0)', '(j=1 source=y.gz)', '([(3)']
我对同一个答案或指向教程同样感到高兴,这使我能够在完成答案后自己找到答案。感谢。
EDIT1:更改了字符串(请参阅下面的答案):
s=string='s=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])] source=4>'
EDIT2:更改字符串(未提供答案,但我会自行提供):
s=string='s=<a=1 b=[(text1 [(text2 source=x.gz i=i.gz)]), ([(text3 j=1.0 source=y.gz)])] c=[([(3)])] d=[([(source=x.gz)])]>'
我试过了:
re.findall(r'(?<=b=)\[\(.*?[\S]*?source=([\w\./]+)', s)
但它只会返回:
['x.gz']
答案 0 :(得分:4)
使用capturing groups捕获要打印的字符。
>>> string = 's=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])] source=4>'
>>> re.findall(r'\(\[\([^\[\]()]*source=([\w.]+)', string)
['x.gz', 'y.gz']
<强>解释强>
\(\[\(
字面上匹配([(
个字符。[^\[\]()]*
一个否定的字符类,匹配任何字符,但不匹配[
或]
或(
或)
零次或多次。source=
匹配字符串source=
([\w.]+)
一次或多次捕获单词字符或点。<强>更新强>
>>> string = 's=<a=1 b=[(text1 [(text2 source=x.gz i=i.gz)]), ([(text3 j=1.0 source=y.gz)])] c=[([(3)])] d=[([(source=x.gz)])]>'
>>> re.findall(r'\([^\[\]()]*\[\([^\[\]()]+source=([\w.]+)', string)
['x.gz', 'y.gz']
答案 1 :(得分:3)
如果你只想要source
值,也许你可以使用它:
>>> re.findall(r'source=([\w\.]+)', s)
['x.gz', 'y.gz']
此正则表达式指定应捕获source=
之后显示的内容,只要它是句点.
或字母数字字符。
修改:更新后的字符串:
>>> s = 's=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])] source=4>'
>>> re.findall(r'\[\([\w=\s]*source=([\w\.]+)', s)
['x.gz', 'y.gz']
现在正则表达式指定source=
必须以[(
开头,并且在[\w=\s]
集(字母数字,=
,空格)中包含零个或多个字符。
编辑2 :与上面几乎完全相同,只是[\w=\s]
已扩展为包含.
:
>>> s = 's=<a=1 b=[(text1 [(text2 source=x.gz i=i.gz)]), ([(text3 j=1.0 source=y.gz)])] c=[([(3)])] d=[([(source=x.gz)])]>'
>>> re.findall(r'\[\([\w=\.\s]*source=([\w\.]+)', s)
['x.gz', 'y.gz', 'x.gz']
答案 2 :(得分:2)
这个正则表达式发现所有的来源=在肠胃外。
s='s=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])]>'
re.findall(r"source=(\S+?)(?:\s|[)])",s)
['x.gz', 'y.gz']
如果你只想要那些([(和)])
re.findall(r"[(]\[[(][\s\S]*?source=([\w\.]+)[\s\S]*?[)]\][)]",s)
我从大学开始就接受了正则表达式的攻击,但自从我开始阅读PERL regex guide后,我开始喜欢正则表达式。
答案 3 :(得分:0)
您可以使用the new regex module中的一个很好的功能,它允许从重复捕获组中提取所有结果。请注意,同一模块也允许使用重复的命名捕获。
示例:
import regex
s = 's=<a=1 b=[([(source=x.gz i=0)]), ([(j=1 source=y.gz)])] c=[([(3)])] source=4>'
# description of an element
elt = r'''\( [^[]* \[\(
(?>
\b source=(?<source> [^\s)]+ )
|
[^s)]+
|
\Bs+
|
s(?!ource=)
)*
\)\]\)
'''
p = regex.compile(r'b=\[%s(?:,\ *%s)*' % (elt, elt), regex.VERBOSE);
m = p.search(s)
print(m.captures('source'))
结果:
['x.gz', 'y.gz']
这种方法的主要兴趣在于您可以处理未定义数量的元素,并确保这些元素来自您选择的值(a,b,c ...)。
请注意,对于这种方法,不再需要findall
方法,因为重复在模式本身中,因此search
方法就足够了。
答案 4 :(得分:0)
这也会产生结果:
re.findall(r'source=([a-z]+\.[a-z]+)',s,re.I)
['x.gz', 'y.gz']
适用于所有编辑。 re.I 设置不区分大小写的标记。