我有这个字符串:
s = MY_FUNC(AVG, WFC US EQUITY, WFC US EQUITY, ">+3%", 1,1,7)
这个正则表达式搜索parens,逗号和简单的运算符。我需要排除双引号内的任何匹配,并能够在匹配上拆分。请注意,解决方案仍必须在字符串的其余部分中搜索parens,逗号和运算符。 当前版本的正则表达式是:
tokenize_regex = re.compile(r'([\[\]\(\)\+\-\*/<>=!,])')
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'']
答案 0 :(得分:1)
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
# ...
]
然后你用这些来制作一个主正则表达式:
groups = ('(?P<{}>{})'.format(ltype, regex) for ltype, regex in lexical_types)
tokenizer = re.compile('|'.join(groups))
然后将要标记的字符串传递给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
,你将获得一个匹配对象流,其中包含你可能想知道的关于字符串的所有内容(词汇方式,即)。您可能想要做的是根据其词法类型处理每个匹配对象。对于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