Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:捕获并返回量词中的每个元素_Python_Regex - Fatal编程技术网

Python:捕获并返回量词中的每个元素

Python:捕获并返回量词中的每个元素,python,regex,Python,Regex,给定这样一组字符串:60=60,100=60+30+10,200=120+50+30,300=200+100,180=60+50+40+20+10我需要一个正则表达式来解析(并验证)这些字符串。匹配应严格(例如,数字和运算符之间不允许有空格) 我最终得到了一个类似于(\d+)=(\d+(:\+(\d+)))* 它完美地匹配了它们,但使用re.match(regex,string).groups()提取匹配项时返回('100','60','10'),('200','120','30') 请参阅,*

给定这样一组字符串:
60=60
100=60+30+10
200=120+50+30
300=200+100
180=60+50+40+20+10
我需要一个正则表达式来解析(并验证)这些字符串。匹配应严格(例如,数字和运算符之间不允许有空格)

我最终得到了一个类似于
(\d+)=(\d+(:\+(\d+)))*

它完美地匹配了它们,但使用
re.match(regex,string).groups()提取匹配项时返回
('100','60','10')
('200','120','30')

请参阅,
*
量词仅匹配最后一个数字!这是意料之中的,但不能解决我的问题

*
量词下分别返回所有匹配项的最适合的方法是什么?因此我可以轻松地
断言res[0]==sum(res[1:])


目前,我独立地匹配每个位,存储最后一个匹配位置并从该位置继续解析,但它看起来有点难看。

如果
+
是您可以得到的唯一运算符,(正如我从您提到的
sum()
的事实中所假设的那样),您不需要正则表达式。只需使用常规的
.split()


如果
+
是您可以获得的唯一运算符(根据您提到的
sum()
),那么您不需要正则表达式。只需使用常规的
.split()


不使用正则表达式,而是使用解析器怎么样

from pyparsing import *

integer = Word(nums).setParseAction(lambda t:int(t[0]))
variable = Word(alphas,exact=1)
operand = integer | variable

expop = Literal('^')
signop = oneOf('+ -')
multop = oneOf('* /')
plusop = oneOf('+ -')
factop = Literal('!')
equalop = Literal('=')

expr = operatorPrecedence( operand,
    [("=", 2, opAssoc.LEFT),
     ("+", 2, opAssoc.RIGHT),]
    )


test=['60=60', '70=10+20', '100=1+2+42+67']

for t in test:
    print t, u'→', expr.parseString(t)
    print
然后输出:

60=60 → [[60, '=', 60]]

70=10+20 → [[[70, '=', 10], '+', 20]]

100=1+2+42+67 → [[[100, '=', 1], '+', [2, '+', [42, '+', 67]]]]
然后要得到整数,只需展平树并查找所有整数


另一种方法是在
+
=
上拆分字符串,我发现这种方法稍微不那么优雅,并且不会对字符串进行语法检查:

for t in test:
    head, tail = t.split('=')
    values = [head] + tail.split('+')
    print t, u'→', values
其中:

60=60 → ['60', '60']
70=10+20 → ['70', '10', '20']
100=1+2+42+67 → ['100', '1', '2', '42', '67']
最后,我们可以试着找到一个regex魔弹来回答你的问题,但老实说,这不是我解决这个问题的方法


注意:要将列表展平,有一种方法:

def flatten(seq):
    res = []
    for item in seq:
        if (isinstance(item, (tuple, list))):
            res.extend(flatten(item))
        else:
            res.append(item)
    return res

不使用正则表达式,而是使用解析器怎么样

from pyparsing import *

integer = Word(nums).setParseAction(lambda t:int(t[0]))
variable = Word(alphas,exact=1)
operand = integer | variable

expop = Literal('^')
signop = oneOf('+ -')
multop = oneOf('* /')
plusop = oneOf('+ -')
factop = Literal('!')
equalop = Literal('=')

expr = operatorPrecedence( operand,
    [("=", 2, opAssoc.LEFT),
     ("+", 2, opAssoc.RIGHT),]
    )


test=['60=60', '70=10+20', '100=1+2+42+67']

for t in test:
    print t, u'→', expr.parseString(t)
    print
然后输出:

60=60 → [[60, '=', 60]]

70=10+20 → [[[70, '=', 10], '+', 20]]

100=1+2+42+67 → [[[100, '=', 1], '+', [2, '+', [42, '+', 67]]]]
然后要得到整数,只需展平树并查找所有整数


另一种方法是在
+
=
上拆分字符串,我发现这种方法稍微不那么优雅,并且不会对字符串进行语法检查:

for t in test:
    head, tail = t.split('=')
    values = [head] + tail.split('+')
    print t, u'→', values
其中:

60=60 → ['60', '60']
70=10+20 → ['70', '10', '20']
100=1+2+42+67 → ['100', '1', '2', '42', '67']
最后,我们可以试着找到一个regex魔弹来回答你的问题,但老实说,这不是我解决这个问题的方法


注意:要将列表展平,有一种方法:

def flatten(seq):
    res = []
    for item in seq:
        if (isinstance(item, (tuple, list))):
            res.extend(flatten(item))
        else:
            res.append(item)
    return res

尝试python内置函数
eval
在运行时计算表达式。我把正则表达式改成了一点点。它是通用的,可以很容易地用于任何数学运算

import re

data = "100=60+30+10, 200=120+50+30, 300=200+100, 180=60+50+40+20+10"

rx = r"(\d+)=([^, ]+)"

for res in re.finditer(rx, data, re.IGNORECASE | re.MULTILINE):
    lhs = eval(res.group(1))
    rhs = eval(res.group(2))
    assert lhs == rhs
如果您想从代码片段中获得一些乐趣,请将regex替换为:

rx = r"([+-]?\d+(?:\.\d+))=([^, ]+)"

现在您也可以计算正数、负数、整数和十进制数。

尝试python内置函数
eval
在运行时计算表达式。我把正则表达式改成了一点点。它是通用的,可以很容易地用于任何数学运算

import re

data = "100=60+30+10, 200=120+50+30, 300=200+100, 180=60+50+40+20+10"

rx = r"(\d+)=([^, ]+)"

for res in re.finditer(rx, data, re.IGNORECASE | re.MULTILINE):
    lhs = eval(res.group(1))
    rhs = eval(res.group(2))
    assert lhs == rhs
如果您想从代码片段中获得一些乐趣,请将regex替换为:

rx = r"([+-]?\d+(?:\.\d+))=([^, ]+)"

现在您也可以计算正数、负数、整数和十进制数。

使用正则表达式(Python 2.7)似乎很容易解决:


使用正则表达式(Python 2.7)似乎很容易解决:


总是有两个
+
操作符吗?不,我会添加更多的例子。请参阅下面我的帖子。您也可以轻松地计算+-和十进制数,不会有太多困难。为什么数字和运算符之间不允许有空格。那样太复杂了吗?您是在验证还是在解析??您不会使用Pythons regex引擎单独获取所有RHS值。只要像这样匹配它,
(\d+)=(\d+(?:\+\d+*)
,组1是LHS,组2必须在
+
上拆分以形成一个数组。总结数组,将其与LHS值进行比较。是否总是有两个
+
运算符?不,我将添加更多示例请参阅下面的帖子。您也可以轻松地计算+-和十进制数,不会有太多困难。为什么数字和运算符之间不允许有空格。那样太复杂了吗?您是在验证还是在解析??您不会使用Pythons regex引擎单独获取所有RHS值。只要像这样匹配它,
(\d+)=(\d+(?:\+\d+*)
,组1是LHS,组2必须在
+
上拆分以形成一个数组。对数组求和,并将其与LHS值进行比较。它将用空格
100=50+30+20
匹配字符串,但它们应该匹配fail@dmzkrsk:好的。我添加了
.strip()
等一下。你想让它失败吗?它本来是我的风格,但现在我更改了它,我不确定这是否是您想要的。它将匹配带空格的字符串
100=50+30+20
,但它们应该匹配fail@dmzkrsk:好的。我添加了
.strip()
等一下。你想让它失败吗?它本来是我的风格,但现在我改变了它,我不确定这是否是你想要的。