Python根据条件拆分列表值

时间:2019-03-12 10:27:56

标签: python regex

给出基于某些条件的python列表拆分值:

    list = ['(( value(name) = literal(luke) or value(like) = literal(music) ) 
     and (value(PRICELIST) in propval(valid))',
    '(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
     (value(PRICELIST) in propval(valid))'] 

现在列表[0]为

  (( value(name) = literal(luke) or value(like) = literal(music) ) 
     and (value(PRICELIST) in propval(valid))

我想拆分,以便在迭代时得到:

#expected output
value(sam) = literal(abc)
value(like) = literal(music)

如果它以值和文字开头,也是如此。起初,我想到了使用and和or进行拆分,但由于有时可能会缺少and和or,因此无法正常工作。

我尝试过:

for i in list:
i.split()
print(i)
#output ['((', 'value(abc)', '=', 'literal(12)', 'or' .... 

我也欢迎基于正则表达式的建议。但是我对此几乎一无所知,我宁愿不包含它

3 个答案:

答案 0 :(得分:1)

@Duck_dragon

您在开头帖子列表中的字符串经过格式化,导致在Python中引起语法错误。在下面提供的示例中,我对其进行了编辑以使用'''

>>> import re
>>> list = ['''(( value(name) = literal(luke) or value(like) = literal(music) ) 
 and (value(PRICELIST) in propval(valid))''',
'''(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
 (value(PRICELIST) in propval(valid))''']


#Simple findall without setting it equal to a variable so it returns a list of separate strings but which you can't use
#You can also use the *MORE SIMPLE* but less flexible regex:  '([a-zA-Z]+\([a-zA-Z]+\)[\s=]+[a-zA-Z]+\([a-zA-Z]+\))'
>>> for item in list:
        re.findall('([a-zA-Z]+(?:\()[a-zA-Z]+(?:\))[\s=]+[a-zA-Z]+(?:\()[a-zA-Z]+(?:\)))', item)    

    ['value(name) = literal(luke)', 'value(like) = literal(music)']
    ['value(sam) = literal(abc)', 'value(like) = literal(music)']

要更进一步,并为您提供一个可以使用的阵列:

>>> import re
>>> list = ['''(( value(name) = literal(luke) or value(like) = literal(music) ) 
 and (value(PRICELIST) in propval(valid))''',
'''(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
 (value(PRICELIST) in propval(valid))''']


#Declaring blank array found_list which you can use to call the individual items
>>> found_list = []
>>> for item in list:
        for element in re.findall('([a-zA-Z]+(?:\()[a-zA-Z]+(?:\))[\s=]+[a-zA-Z]+(?:\()[a-zA-Z]+(?:\)))', item):
            found_list.append(element)


>>> found_list
['value(name) = literal(luke)', 'value(like) = literal(music)', 'value(sam) = literal(abc)', 'value(like) = literal(music)']

给出您在下面无法理解的评论,这是您想要的吗?我更改了列表以添加您提到的其他值:

>>> import re
>>> list = ['''(( value(name) = literal(luke) or value(like) = literal(music) ) 
and (value(PRICELIST) in propval(valid))''',
'''(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
(value(PRICELIST) in propval(valid))''',
'''(value(PICK_SKU1) = propval(._sku)''', '''propval(._amEntitled) > literal(0))''']


>>> found_list = []
>>> for item in list:
        for element in re.findall('([\w\.]+(?:\()[\w\.]+(?:\))[\s=<>(?:in)]+[\w\.]+(?:\()[\w\.]+(?:\)))', item):
            found_list.append(element)

>>> found_list
['value(name) = literal(luke)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)', 'value(sam) = literal(abc)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)', 'value(PICK_SKU1) = propval(._sku)', 'propval(._amEntitled) > literal(0)']

编辑:还是您想要的?

>>> import re
>>> list = ['''(( value(name) = literal(luke) or value(like) = literal(music) ) 
 and (value(PRICELIST) in propval(valid))''',
'''(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
 (value(PRICELIST) in propval(valid))''']


#Declaring blank array found_list which you can use to call the individual items
>>> found_list = []
>>> for item in list:
        for element in re.findall('([a-zA-Z]+(?:\()[a-zA-Z]+(?:\))[\s=<>(?:in)]+[a-zA-Z]+(?:\()[a-zA-Z]+(?:\)))', item):
            found_list.append(element)


>>> found_list
['value(name) = literal(luke)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)', 'value(sam) = literal(abc)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)']

让我知道是否需要解释。

@Fyodor Kutsepin

在您的示例中,取出your_list_并替换为OP的list以避免混淆。其次,您的for loop缺少:会产生语法错误

答案 1 :(得分:1)

因此,为了避免造成太多混乱,我将在此评论中解释解决方案。我希望可以。

鉴于您的评论(我对此不太理解),这是您想要的吗?我更改了列表以添加您提到的其他值:

>>> import re
>>> list = ['''(( value(name) = literal(luke) or value(like) = literal(music) ) 
and (value(PRICELIST) in propval(valid))''',
'''(( value(sam) = literal(abc) or value(like) = literal(music) ) and 
(value(PRICELIST) in propval(valid))''',
'''(value(PICK_SKU1) = propval(._sku)''', '''propval(._amEntitled) > literal(0))''']


>>> found_list = []
>>> for item in list:
        for element in re.findall('([\w\.]+(?:\()[\w\.]+(?:\))[\s=<>(?:in)]+[\w\.]+(?:\()[\w\.]+(?:\)))', item):
            found_list.append(element)

>>> found_list
['value(name) = literal(luke)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)', 'value(sam) = literal(abc)', 'value(like) = literal(music)', 'value(PRICELIST) in propval(valid)', 'value(PICK_SKU1) = propval(._sku)', 'propval(._amEntitled) > literal(0)']

说明:

  • 预注意事项-我将[a-zA-Z0-9\._]+更改为[\w\.]+,因为它们本质上是相同的东西,但更简洁。我将在下一步中解释这些查询包含哪些字符
  • 对于([\w\.]+,注意到它是“未封闭的”,这意味着我正在启动正则表达式以捕获以下查询中的所有内容,我告诉它首先捕获{{1}范围内的所有字符},a-zA-Z,以及转义期(_
  • 对于.,我是说捕获的查询应包含转义的“开头”括号((?:\()
  • 使用(是要再次在括号中加上第二步中概述的单词字符,但是这次是通过[\w\.]+(?:\))我是说要在其后面加上转义的“结束”括号( (?:\))
  • )有点鲁ck,但出于可读性考虑,并假设您的字符串将保持相对一致,这表示,在“右括号”后面应加上[\s=<>(?:in)]+,{{ 1}},"whitespace"=或单词<,但顺序却很多次,但它们都是一致出现的。这是鲁re的,因为它还会匹配>in等内容。但是,使其更加具体可能很容易导致丢失捕获内容
  • 我再次说<< <,是从第1步中找到单词character,然后是一个“开括号”,再一次是单词character,再是一个“闭合括号”
  • 使用= in > =关闭“未关闭”捕获组(记住上面第一个捕获组以“未关闭”开始),以告诉正则表达式引擎捕获我概述的整个查询

希望这会有所帮助

答案 2 :(得分:0)

首先,我建议您避免像内置函数那样命名变量。 其次,如果要获得上述输出,则不需要正则表达式。

例如:

first, rest = your_list_[1].split(') and'):
for item in first[2:].split('or')
    print(item)