Python regex,排除引号中的匹配项

2024-09-28 21:04:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一根绳子:

s = MY_FUNC(AVG, WFC US EQUITY, WFC US EQUITY, ">+3%", 1,1,7)

这个正则表达式搜索paren、逗号和简单运算符。我需要排除双引号内的任何匹配项,并能够在匹配项上拆分。请注意,解决方案仍然必须在字符串的其余部分搜索paren、逗号和运算符。 regex的当前版本是:

^{pr2}$

s的匹配项为:

Match 1
1.  (
Match 2
1.  ,
Match 3
1.  ,
Match 4
1.  ,
Match 5
1.  >
Match 6
1.  +
Match 7
1.  ,
Match 8
1.  ,
Match 9
1.  ,
Match 10
1.  )

当我这样做的时候:

    tokens = Formula.tokenize_regex.split(self.formula)
    print 'tokens: ' + str(tokens)

它返回:

tokens: [u'MY_FUNC', u'(', u'AVG', u',', u' WFC US EQUITY', u',', u' WFC US EQUITY', u',', u' "', u'>', u'', u'+', u'3%"', u',', u' 1', u',', u'1', u',', u'7', u')', u'']

但是我需要它来排除报价中的数量,所以匹配应该是:

Match 1
1.  (
Match 2
1.  ,
Match 3
1.  ,
Match 4
1.  ,
Match 5
1.  ,
Match 6
1.  ,
Match 7
1.  ,
Match 8
1.  )

代币应该是:

tokens: [u'MY_FUNC', u'(', u'AVG', u',', u' WFC US EQUITY', u',', u' WFC US EQUITY', u',', u'">+3%"', u',', u' 1', u',', u'1', u',', u'7', u')', u'']

Tags: mymatch运算符regexavgusfunc逗号
1条回答
网友
1楼 · 发布于 2024-09-28 21:04:36

re.split不是进行标记化的干净方法。在re的文档中有一个recipe,它将更好地为您服务。基本上,首先为每个词法类型编写一个正则表达式。例如:

lexical_types = [
    ('QUOTED_CONTENT', r'"[^"]*?"'),
    ('PAREN', r'[()]'),
    ('OPERATOR', r'[-+<>]'),
    ('COMMA', r','),
    ('IDENTIFIER', r'[A-Z_][ A-Z_]*'),  # our identifier can have spaces in it
    # ...
]

然后您可以使用以下内容创建主正则表达式:

^{pr2}$

然后将要标记的字符串传递给tokenizer.finditer

s = 'MY_FUNC(AVG, WFC US EQUITY, WFC US EQUITY, ">+3%", 1,1,7)'
token_iter = tokenizer.finditer(s)  # an iterator

现在,如果您迭代token_iter,您将得到一个match对象流,其中包含您可能想知道的关于字符串的所有信息(即从词法上讲)。您可能要做的是根据每个匹配对象的词法类型来处理它。对于demo,让我们打印出词法类型、匹配的字符串以及匹配字符串的位置:

for token in token_iter:
    ltype = token.lastgroup  # lexical type of the token
    print(ltype, token.group(ltype), token.span(ltype), sep='   ')

输出

IDENTIFIER   MY_FUNC   (0, 7)
PAREN   (   (7, 8)
IDENTIFIER   AVG   (8, 11)
COMMA   ,   (11, 12)
IDENTIFIER   WFC US EQUITY   (13, 26)
COMMA   ,   (26, 27)
IDENTIFIER   WFC US EQUITY   (28, 41)
COMMA   ,   (41, 42)
QUOTED_CONTENT   ">+3%"   (43, 49)
COMMA   ,   (49, 50)
COMMA   ,   (52, 53)
COMMA   ,   (54, 55)
PAREN   )   (56, 57)

注意:编译主正则表达式时,必须确保优先级较高的模式优先于优先级较低的模式。所以报价应该排在一切之前。由两个字符组成的运算符(如!=)应该在由一个字符组成的运算符之前。在

此模式将处理单引号和双引号:

r"""(?:'[^']*?'|"[^"]*?")"""  # grouped for readability

相关问题 更多 >