在python中用括号括起一个可变数量的实例

时间:2016-07-27 22:36:55

标签: python regex search find substitution

我有一个字符串,其中包含由'和'或'或' x [1]和x [2]或x [分隔的变量名称3]&#39 ;.变量名称的数量不同,它是否是'和'或者'或'介于他们之间。我想围绕由'或's分隔的每一段变量包围括号。例如,如果字符串是' x [1]和x [2]或x [3]和x [4]或x [5]或x [6]和x [7]',我想将其更改为' x [1]和(x [2]或x [3])和(x [4]或x [5]或x [6])和x [7]&# 39;

我甚至不是正则表达式的新手。我想知道在python中使用正则表达式是否有一种相当优雅和有效的方法来做到这一点?任何帮助都会有很大的帮助。

约什

2 个答案:

答案 0 :(得分:1)

这可能会做你想要的:

import re

s = 'x[1] and x[2] or x[3] and x[4] or x[5] or x[6] and x[7]'
s = re.sub(r'(\S+(?:\s*or\s*\S+)+)', r'(\1)', s)
assert s == 'x[1] and (x[2] or x[3]) and (x[4] or x[5] or x[6]) and x[7]'

编辑:一个稍微强大的表达式和更多测试用例:

import re

tests = (
    ('x[1] and x[2] or x[3] and x[4] or x[5] or x[6] and x[7]',
    'x[1] and (x[2] or x[3]) and (x[4] or x[5] or x[6]) and x[7]'),
    ('door and floor', 'door and floor'),
    ('more and more and more', 'more and more and more')
)
for test, expected in tests:
    actual = re.sub(r'\S+(?:\s*\bor\b\s*\S+)+', r'(\g<0>)', test)
    assert actual == expected

答案 1 :(得分:0)

由于你已经有一个正则表达式方法的答案,这里有一个不需要正则表达式的方法:

>>> s = 'x[1] and x[2] or x[3] and x[4] or x[5] or x[6] and x[7]'
>>> ' and '.join(['(%s)' % w if ' or ' in w else w for w in s.split(' and ')])
'x[1] and (x[2] or x[3]) and (x[4] or x[5] or x[6]) and x[7]'

如何运作

第一步是分开and

>>> s.split(' and ')
['x[1]', 'x[2] or x[3]', 'x[4] or x[5] or x[6]', 'x[7]']

下一步是确定子串是否需要被parens包围。这是通过三元声明完成的:

>>> w = 'x[2] or x[3]'; '(%s)' % w if ' or ' in w else w
'(x[2] or x[3])'
>>> w = 'x[1]'; '(%s)' % w if ' or ' in w else w
'x[1]'

最后一步是使用' and '.join(...)重新组合字符串。