Python根据条件拆分列表值

问题描述 投票:1回答:4

给定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)

如果从价值和文字开始,那也是如此。起初我想与分裂,或者,但是它不会起作用,因为有时候可能会丢失,或者。

我试过了 :

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

我对基于正则表达式的建议持开放态度。但我不知道它我不想包括它

python regex
4个回答
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\.]+,注意它是“unclosed”意味着我正在启动正则表达式以捕获以下查询中的所有内容,我告诉它首先捕获a-zA-Z_范围内的所有字符,以及转义期(.
  • 使用(?:\()我说捕获的查询应该包含一个转义的“开放”括号((
  • 随着[\w\.]+(?:\)),我说再次使用第二步中概述的字符字符,但这次通过(?:\))我说跟随他们的逃避“关闭”括号()
  • 这个[\s=<>(?:in)]+有点鲁莽,但为了便于阅读,并假设你的字符串将保持相对一致,这就是说,“右括号”应该跟随"whitespace"=<>in这个词,无论如何,它们都会以任何顺序一致地出现。它是鲁莽的,因为它也会匹配<< <= in > =等等。为了使它更具体,很容易导致丢失捕获
  • [\w\.]+(?:\()[\w\.]+(?:\))我再说一遍,找到第1步中的单词字符,然后是“左括号”,再单词是字符,接着是“右括号”
  • 使用)我正在关闭“未关闭”捕获组(请记住上面的第一个捕获组开始为“未关闭”),告诉正则表达式引擎捕获我已概述的整个查询

希望这可以帮助


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邀请

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


0
投票

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

例如:

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

0
投票

不是说你应该,但你绝对可以在这里使用qazxsw poi解析器:

PEG

这产生了

from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor

data = ['(( 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))']

grammar = Grammar(
    r"""
    expr        = term (operator term)*
    term        = lpar* factor (operator needle)* rpar*
    factor      = needle operator needle

    needle      = word lpar word rpar

    operator    = ws? ("=" / "or" / "and" / "in") ws?
    word        = ~"\w+"

    lpar        = "(" ws?
    rpar        = ws? ")"
    ws          = ~r"\s*"
    """
)

class HorribleStuff(NodeVisitor):
    def generic_visit(self, node, visited_children):
        return node.text or visited_children

    def visit_factor(self, node, children):
        output, equal = [], False

        for child in node.children:
            if (child.expr.name == 'needle'):
                output.append(child.text)
            elif (child.expr.name == 'operator' and child.text.strip() == '='):
                equal = True

        if equal:
            print(output)

for d in data:
    tree = grammar.parse(d)
    hs = HorribleStuff()
    hs.visit(tree)
© www.soinside.com 2019 - 2024. All rights reserved.