Python 正则表达式:匹配和分组可变数量的空格分隔字
我有一个字符串:Python 正则表达式:匹配和分组可变数量的空格分隔字,python,regex,Python,Regex,我有一个字符串: "foo hello world baz 33" foo和baz之间的部分将是一些空格分隔的单词(一个或多个)。我想将此字符串与re匹配,re将对这些单词进行分组: >>> re.match(r'foo (<some re here>) baz (\d+)', "foo hello world baz 33").groups() ('hello', 'world', '33') >re.match(r'foo()baz(\d+),“foo h
"foo hello world baz 33"
foo
和baz
之间的部分将是一些空格分隔的单词(一个或多个)。我想将此字符串与re匹配,re将对这些单词进行分组:
>>> re.match(r'foo (<some re here>) baz (\d+)', "foo hello world baz 33").groups()
('hello', 'world', '33')
>re.match(r'foo()baz(\d+),“foo hello world baz 33”).groups()
(‘你好’、‘世界’、‘33’)
re应具有灵活性,以便在周围没有文字的情况下工作:
>>> re.match(r'(<some re here>)', "hello world").groups()
('hello', 'world')
>>re.match(r'(),“hello world”).groups()
(‘你好’、‘世界’)
我正在尝试使用
([\w++\s])++
的变体,但无法捕获动态确定的组数。这是可能的吗?re.match
在字符串开头返回结果。改用re.search
。*?
返回两个单词/表达式之间的最短匹配(.means anything,*表示0次或多次出现,?表示最短匹配)
编辑:
如果缺少foo或baz,并且需要返回整个字符串,请使用,否则使用:
if p is not None:
result = p.group(1).split()
else:
result = my_str
为什么模式中的?
:
假设单词baz
多次出现:
my_str = "foo hello world baz 33 there is another baz"
使用pattern='foo\s(.*)\sbaz'
将匹配(最长和最贪婪):
然而,使用pattern='foo\s(.*?\sbaz'
将返回最短匹配:
'hello world'
[这不是一个解决方案,但我试图解释为什么不可能]
你想要的是这样的东西:
最酷的部分是重复捕获组的(\w++\s)+
。
问题是大多数正则表达式只存储了捕获组中的最后一个匹配项;旧的捕获被覆盖
我建议使用更简单的正则表达式在字符串上循环
希望它能帮助使用索引找到foo
和baz
。然后split
子字符串
def find_between( s, first, last ):
try:
start = s.index( first ) + len( first )
end = s.index( last, start )
return s[start:end].split()
except ValueError:
return ""
s = "foo hello world baz 33"
start = "foo"
end = "baz"
print find_between(s,start,end)
您需要一个re.findall
和3个捕获组:re.findall(r'^foo(\S+)(\S+)baz(\d+),“foo hello world baz 33”)
。看,这行不通。这里可能有任意数量的单词。所以“foo hello baz 33”不会有问题,我更新了。正则表达式可以是r'^foo(\S+(?:\S+\S+*)(\S+)baz(\d+)
。或者,您希望将第一个捕获组中的单词进行拆分吗?那么,没有额外的操作是不可能的。只有正则表达式不行。由于字符串是空格分隔的单词,请使用.split
函数。我建议不要依赖正则表达式来完成这么简单的任务。@Neil:这取决于你需要它如何工作。信息技术作为附加步骤,您必须拆分结果数组的第一个元素。在Python中使用单个正则表达式是不可能的。非捕获组是不必要的,应该删除。除此之外,这可能是最好的解决方案。也许还可以在结尾添加一些解释33
。OP在问题的评论中询问foo和bar之间的匹配。感谢您的反馈,我们将进行更改:)是的,规格有点模糊。:)理想情况下,模式应该匹配,而不假设有foo和/或baz。因此,“helloworld”是一个可能的字符串,应该返回('hello','world')。威尔,我在行动中对此不清楚clarify@Sword需要“?”吗?如果没有它,我刚才提到的案例将是一个与supportedA相关的问题,这里有一个类似的答案:
'hello world'
foo\s(\w+\s)+baz\s(\d+)
def find_between( s, first, last ):
try:
start = s.index( first ) + len( first )
end = s.index( last, start )
return s[start:end].split()
except ValueError:
return ""
s = "foo hello world baz 33"
start = "foo"
end = "baz"
print find_between(s,start,end)